diff options
Diffstat (limited to 'lib/private')
-rw-r--r-- | lib/private/appframework/dependencyinjection/dicontainer.php | 5 | ||||
-rw-r--r-- | lib/private/connector/sabre/directory.php | 17 | ||||
-rw-r--r-- | lib/private/connector/sabre/file.php | 6 | ||||
-rw-r--r-- | lib/private/connector/sabre/filesplugin.php | 73 | ||||
-rw-r--r-- | lib/private/connector/sabre/node.php | 23 | ||||
-rw-r--r-- | lib/private/db/connection.php | 2 | ||||
-rw-r--r-- | lib/private/db/connectionwrapper.php | 99 | ||||
-rw-r--r-- | lib/private/filechunking.php | 10 | ||||
-rw-r--r-- | lib/private/files/cache/cache.php | 16 | ||||
-rw-r--r-- | lib/private/files/cache/scanner.php | 36 | ||||
-rw-r--r-- | lib/private/server.php | 3 | ||||
-rw-r--r-- | lib/private/urlgenerator.php | 18 |
12 files changed, 285 insertions, 23 deletions
diff --git a/lib/private/appframework/dependencyinjection/dicontainer.php b/lib/private/appframework/dependencyinjection/dicontainer.php index ae2c5e8546b..e2ea974e104 100644 --- a/lib/private/appframework/dependencyinjection/dicontainer.php +++ b/lib/private/appframework/dependencyinjection/dicontainer.php @@ -88,8 +88,9 @@ class DIContainer extends SimpleContainer implements IAppContainer{ /** * Middleware */ - $this['SecurityMiddleware'] = $this->share(function($c){ - return new SecurityMiddleware($this, $c['Request']); + $app = $this; + $this['SecurityMiddleware'] = $this->share(function($c) use ($app){ + return new SecurityMiddleware($app, $c['Request']); }); $middleWares = $this->middleWares; diff --git a/lib/private/connector/sabre/directory.php b/lib/private/connector/sabre/directory.php index c51f84bf67c..02d1a9f4ba2 100644 --- a/lib/private/connector/sabre/directory.php +++ b/lib/private/connector/sabre/directory.php @@ -50,6 +50,10 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa */ public function createFile($name, $data = null) { + if ($name === 'Shared' && empty($this->path)) { + throw new \Sabre_DAV_Exception_Forbidden(); + } + // for chunked upload also updating a existing file is a "createFile" // because we create all the chunks before reasamble them to the existing file. if (isset($_SERVER['HTTP_OC_CHUNKED'])) { @@ -82,6 +86,10 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa */ public function createDirectory($name) { + if ($name === 'Shared' && empty($this->path)) { + throw new \Sabre_DAV_Exception_Forbidden(); + } + if (!\OC\Files\Filesystem::isCreatable($this->path)) { throw new \Sabre_DAV_Exception_Forbidden(); } @@ -187,13 +195,16 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa */ public function delete() { - if (!\OC\Files\Filesystem::isDeletable($this->path)) { + if ($this->path === 'Shared') { throw new \Sabre_DAV_Exception_Forbidden(); } - if ($this->path != "/Shared") { - \OC\Files\Filesystem::rmdir($this->path); + + if (!\OC\Files\Filesystem::isDeletable($this->path)) { + throw new \Sabre_DAV_Exception_Forbidden(); } + \OC\Files\Filesystem::rmdir($this->path); + } /** diff --git a/lib/private/connector/sabre/file.php b/lib/private/connector/sabre/file.php index 6ace8d14484..919bb1fc6f4 100644 --- a/lib/private/connector/sabre/file.php +++ b/lib/private/connector/sabre/file.php @@ -143,6 +143,10 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D */ public function delete() { + if ($this->path === 'Shared') { + throw new \Sabre_DAV_Exception_Forbidden(); + } + if (!\OC\Files\Filesystem::isDeletable($this->path)) { throw new \Sabre_DAV_Exception_Forbidden(); } @@ -218,7 +222,7 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D if (isset($_SERVER['CONTENT_LENGTH'])) { $expected = $_SERVER['CONTENT_LENGTH']; if ($bytesWritten != $expected) { - $chunk_handler->cleanup(); + $chunk_handler->remove($info['index']); throw new Sabre_DAV_Exception_BadRequest( 'expected filesize ' . $expected . ' got ' . $bytesWritten); } diff --git a/lib/private/connector/sabre/filesplugin.php b/lib/private/connector/sabre/filesplugin.php new file mode 100644 index 00000000000..ac781825672 --- /dev/null +++ b/lib/private/connector/sabre/filesplugin.php @@ -0,0 +1,73 @@ +<?php + +/** + * ownCloud + * + * @author Thomas Müller + * @copyright 2013 Thomas Müller <thomas.mueller@tmit.eu> + * + * @license AGPL3 + */ + +class OC_Connector_Sabre_FilesPlugin extends Sabre_DAV_ServerPlugin +{ + + // namespace + const NS_OWNCLOUD = 'http://owncloud.org/ns'; + + /** + * Reference to main server object + * + * @var Sabre_DAV_Server + */ + private $server; + + /** + * This initializes the plugin. + * + * This function is called by Sabre_DAV_Server, after + * addPlugin is called. + * + * This method should set up the required event subscriptions. + * + * @param Sabre_DAV_Server $server + * @return void + */ + public function initialize(Sabre_DAV_Server $server) { + + $server->xmlNamespaces[self::NS_OWNCLOUD] = 'oc'; + $server->protectedProperties[] = '{' . self::NS_OWNCLOUD . '}id'; + + $this->server = $server; + $this->server->subscribeEvent('beforeGetProperties', array($this, 'beforeGetProperties')); + } + + /** + * Adds all ownCloud-specific properties + * + * @param string $path + * @param Sabre_DAV_INode $node + * @param array $requestedProperties + * @param array $returnedProperties + * @return void + */ + public function beforeGetProperties($path, Sabre_DAV_INode $node, array &$requestedProperties, array &$returnedProperties) { + + if ($node instanceof OC_Connector_Sabre_Node) { + + $fileid_propertyname = '{' . self::NS_OWNCLOUD . '}id'; + if (array_search($fileid_propertyname, $requestedProperties)) { + unset($requestedProperties[array_search($fileid_propertyname, $requestedProperties)]); + } + + /** @var $node OC_Connector_Sabre_Node */ + $fileId = $node->getFileId(); + if (!is_null($fileId)) { + $returnedProperties[200][$fileid_propertyname] = $fileId; + } + + } + + } + +} diff --git a/lib/private/connector/sabre/node.php b/lib/private/connector/sabre/node.php index 3c2ad60f1dd..76fbc251100 100644 --- a/lib/private/connector/sabre/node.php +++ b/lib/private/connector/sabre/node.php @@ -45,6 +45,7 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr * @var string */ protected $path; + /** * node fileinfo cache * @var array @@ -211,6 +212,7 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr * properties should be returned */ public function getProperties($properties) { + if (is_null($this->property_cache)) { $sql = 'SELECT * FROM `*PREFIX*properties` WHERE `userid` = ? AND `propertypath` = ?'; $result = OC_DB::executeAudited( $sql, array( OC_User::getUser(), $this->path ) ); @@ -236,8 +238,11 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr $props = array(); foreach($properties as $property) { - if (isset($this->property_cache[$property])) $props[$property] = $this->property_cache[$property]; + if (isset($this->property_cache[$property])) { + $props[$property] = $this->property_cache[$property]; + } } + return $props; } @@ -260,4 +265,20 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr } return $this->fileView; } + + /** + * @return mixed + */ + public function getFileId() + { + $this->getFileinfoCache(); + + if (isset($this->fileinfo_cache['fileid'])) { + $instanceId = OC_Util::getInstanceId(); + $id = sprintf('%08d', $this->fileinfo_cache['fileid']); + return $instanceId . $id; + } + + return null; + } } diff --git a/lib/private/db/connection.php b/lib/private/db/connection.php index 2d3193a148a..2581969dbd0 100644 --- a/lib/private/db/connection.php +++ b/lib/private/db/connection.php @@ -12,7 +12,7 @@ use Doctrine\DBAL\Configuration; use Doctrine\DBAL\Cache\QueryCacheProfile; use Doctrine\Common\EventManager; -class Connection extends \Doctrine\DBAL\Connection implements \OCP\IDBConnection { +class Connection extends \Doctrine\DBAL\Connection { /** * @var string $tablePrefix */ diff --git a/lib/private/db/connectionwrapper.php b/lib/private/db/connectionwrapper.php new file mode 100644 index 00000000000..93d4fb57f74 --- /dev/null +++ b/lib/private/db/connectionwrapper.php @@ -0,0 +1,99 @@ +<?php +/** + * Copyright (c) 2013 Thomas Müller <deepdiver@owncloud.com> + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC\DB; + + +class ConnectionWrapper implements \OCP\IDBConnection { + + private $connection; + + public function __construct(Connection $conn) { + $this->connection = $conn; + } + + /** + * Used to the owncloud database access away + * @param string $sql the sql query with ? placeholder for params + * @param int $limit the maximum number of rows + * @param int $offset from which row we want to start + * @return \Doctrine\DBAL\Driver\Statement The prepared statement. + */ + public function prepare($sql, $limit = null, $offset = null) + { + return $this->connection->prepare($sql, $limit, $offset); + } + + /** + * Used to get the id of the just inserted element + * @param string $tableName the name of the table where we inserted the item + * @return int the id of the inserted element + */ + public function lastInsertId($table = null) + { + return $this->connection->lastInsertId($table); + } + + /** + * Insert a row if a matching row doesn't exists. + * @param string The table name (will replace *PREFIX*) to perform the replace on. + * @param array + * + * The input array if in the form: + * + * array ( 'id' => array ( 'value' => 6, + * 'key' => true + * ), + * 'name' => array ('value' => 'Stoyan'), + * 'family' => array ('value' => 'Stefanov'), + * 'birth_date' => array ('value' => '1975-06-20') + * ); + * @return bool + * + */ + public function insertIfNotExist($table, $input) + { + return $this->connection->insertIfNotExist($table, $input); + } + + /** + * Start a transaction + * @return bool TRUE on success or FALSE on failure + */ + public function beginTransaction() + { + return $this->connection->beginTransaction(); + } + + /** + * Commit the database changes done during a transaction that is in progress + * @return bool TRUE on success or FALSE on failure + */ + public function commit() + { + return $this->connection->commit(); + } + + /** + * Rollback the database changes done during a transaction that is in progress + * @return bool TRUE on success or FALSE on failure + */ + public function rollBack() + { + return $this->connection->rollBack(); + } + + /** + * Gets the error code and message as a string for logging + * @return string + */ + public function getError() + { + return $this->connection->getError(); + } +} diff --git a/lib/private/filechunking.php b/lib/private/filechunking.php index 0dfce696cda..aa4f73c7c05 100644 --- a/lib/private/filechunking.php +++ b/lib/private/filechunking.php @@ -85,6 +85,16 @@ class OC_FileChunking { } } + /** + * Removes one specific chunk + * @param $index + */ + public function remove($index) { + $cache = $this->getCache(); + $prefix = $this->getPrefix(); + $cache->remove($prefix.$index); + } + public function signature_split($orgfile, $input) { $info = unpack('n', fread($input, 2)); $blocksize = $info[1]; diff --git a/lib/private/files/cache/cache.php b/lib/private/files/cache/cache.php index 364a50d377c..fc2d965d7f9 100644 --- a/lib/private/files/cache/cache.php +++ b/lib/private/files/cache/cache.php @@ -69,9 +69,15 @@ class Cache { } if (!isset(self::$mimetypeIds[$mime])) { - $result = \OC_DB::executeAudited('INSERT INTO `*PREFIX*mimetypes`(`mimetype`) VALUES(?)', array($mime)); - self::$mimetypeIds[$mime] = \OC_DB::insertid('*PREFIX*mimetypes'); - self::$mimetypes[self::$mimetypeIds[$mime]] = $mime; + try{ + $result = \OC_DB::executeAudited('INSERT INTO `*PREFIX*mimetypes`(`mimetype`) VALUES(?)', array($mime)); + self::$mimetypeIds[$mime] = \OC_DB::insertid('*PREFIX*mimetypes'); + self::$mimetypes[self::$mimetypeIds[$mime]] = $mime; + } + catch (\Doctrine\DBAL\DBALException $e){ + \OC_Log::write('core', 'Exception during mimetype insertion: ' . $e->getmessage(), \OC_Log::DEBUG); + return -1; + } } return self::$mimetypeIds[$mime]; @@ -84,8 +90,8 @@ class Cache { return isset(self::$mimetypes[$id]) ? self::$mimetypes[$id] : null; } - - protected function loadMimetypes(){ + + public function loadMimetypes(){ $result = \OC_DB::executeAudited('SELECT `id`, `mimetype` FROM `*PREFIX*mimetypes`', array()); if ($result) { while ($row = $result->fetchRow()) { diff --git a/lib/private/files/cache/scanner.php b/lib/private/files/cache/scanner.php index 96f84609cf2..f63abf2d4fc 100644 --- a/lib/private/files/cache/scanner.php +++ b/lib/private/files/cache/scanner.php @@ -190,24 +190,34 @@ class Scanner extends BasicEmitter { } $newChildren = array(); if ($this->storage->is_dir($path) && ($dh = $this->storage->opendir($path))) { + $exceptionOccurred = false; \OC_DB::beginTransaction(); if (is_resource($dh)) { while (($file = readdir($dh)) !== false) { $child = ($path) ? $path . '/' . $file : $file; if (!Filesystem::isIgnoredDir($file)) { $newChildren[] = $file; - $data = $this->scanFile($child, $reuse, true); - if ($data) { - if ($data['size'] === -1) { - if ($recursive === self::SCAN_RECURSIVE) { - $childQueue[] = $child; - } else { - $size = -1; + try { + $data = $this->scanFile($child, $reuse, true); + if ($data) { + if ($data['size'] === -1) { + if ($recursive === self::SCAN_RECURSIVE) { + $childQueue[] = $child; + } else { + $size = -1; + } + } else if ($size !== -1) { + $size += $data['size']; } - } else if ($size !== -1) { - $size += $data['size']; } } + catch (\Doctrine\DBAL\DBALException $ex){ + // might happen if inserting duplicate while a scanning + // process is running in parallel + // log and ignore + \OC_Log::write('core', 'Exception while scanning file "' . $child . '": ' . $ex->getMessage(), \OC_Log::DEBUG); + $exceptionOccurred = true; + } } } } @@ -217,6 +227,14 @@ class Scanner extends BasicEmitter { $this->cache->remove($child); } \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 + // To make sure to have the updated mime types in such cases, + // we reload them here + $this->cache->loadMimetypes(); + } + foreach ($childQueue as $child) { $childSize = $this->scanChildren($child, self::SCAN_RECURSIVE, $reuse); if ($childSize === -1) { diff --git a/lib/private/server.php b/lib/private/server.php index d450907534b..65899f3007e 100644 --- a/lib/private/server.php +++ b/lib/private/server.php @@ -5,6 +5,7 @@ namespace OC; use OC\AppFramework\Http\Request; use OC\AppFramework\Utility\SimpleContainer; use OC\Cache\UserCache; +use OC\DB\ConnectionWrapper; use OC\Files\Node\Root; use OC\Files\View; use OCP\IServerContainer; @@ -289,7 +290,7 @@ class Server extends SimpleContainer implements IServerContainer { * @return \OCP\IDBConnection */ function getDatabaseConnection() { - return \OC_DB::getConnection(); + return new ConnectionWrapper(\OC_DB::getConnection()); } /** diff --git a/lib/private/urlgenerator.php b/lib/private/urlgenerator.php index 5c1d9d825b6..1ec10fe5688 100644 --- a/lib/private/urlgenerator.php +++ b/lib/private/urlgenerator.php @@ -81,17 +81,35 @@ class URLGenerator implements IURLGenerator { // Read the selected theme from the config file $theme = \OC_Util::getTheme(); + //if a theme has a png but not an svg always use the png + $basename = substr(basename($image),0,-4); + // Check if the app is in the app folder if (file_exists(\OC::$SERVERROOT . "/themes/$theme/apps/$app/img/$image")) { return \OC::$WEBROOT . "/themes/$theme/apps/$app/img/$image"; + } elseif (!file_exists(\OC::$SERVERROOT . "/themes/$theme/apps/$app/img/$basename.svg") + && file_exists(\OC::$SERVERROOT . "/themes/$theme/apps/$app/img/$basename.png")) { + return \OC::$WEBROOT . "/themes/$theme/apps/$app/img/$basename.png"; } elseif (file_exists(\OC_App::getAppPath($app) . "/img/$image")) { return \OC_App::getAppWebPath($app) . "/img/$image"; + } elseif (!file_exists(\OC_App::getAppPath($app) . "/img/$basename.svg") + && file_exists(\OC_App::getAppPath($app) . "/img/$basename.png")) { + return \OC_App::getAppPath($app) . "/img/$basename.png"; } elseif (!empty($app) and file_exists(\OC::$SERVERROOT . "/themes/$theme/$app/img/$image")) { return \OC::$WEBROOT . "/themes/$theme/$app/img/$image"; + } elseif (!empty($app) and (!file_exists(\OC::$SERVERROOT . "/themes/$theme/$app/img/$basename.svg") + && file_exists(\OC::$WEBROOT . "/themes/$theme/$app/img/$basename.png"))) { + return \OC::$WEBROOT . "/themes/$theme/$app/img/$basename.png"; } elseif (!empty($app) and file_exists(\OC::$SERVERROOT . "/$app/img/$image")) { return \OC::$WEBROOT . "/$app/img/$image"; + } elseif (!empty($app) and (!file_exists(\OC::$SERVERROOT . "/$app/img/$basename.svg") + && file_exists(\OC::$WEBROOT . "/$app/img/$basename.png"))) { + return \OC::$WEBROOT . "/$app/img/$basename.png"; } elseif (file_exists(\OC::$SERVERROOT . "/themes/$theme/core/img/$image")) { return \OC::$WEBROOT . "/themes/$theme/core/img/$image"; + } elseif (!file_exists(\OC::$SERVERROOT . "/themes/$theme/core/img/$basename.svg") + && file_exists(\OC::$SERVERROOT . "/themes/$theme/core/img/$basename.png")) { + return \OC::$WEBROOT . "/themes/$theme/core/img/$basename.png"; } elseif (file_exists(\OC::$SERVERROOT . "/core/img/$image")) { return \OC::$WEBROOT . "/core/img/$image"; } else { |