summaryrefslogtreecommitdiffstats
path: root/lib/private
diff options
context:
space:
mode:
Diffstat (limited to 'lib/private')
-rw-r--r--lib/private/appframework/dependencyinjection/dicontainer.php5
-rw-r--r--lib/private/connector/sabre/directory.php17
-rw-r--r--lib/private/connector/sabre/file.php6
-rw-r--r--lib/private/connector/sabre/filesplugin.php73
-rw-r--r--lib/private/connector/sabre/node.php23
-rw-r--r--lib/private/db/connection.php2
-rw-r--r--lib/private/db/connectionwrapper.php99
-rw-r--r--lib/private/filechunking.php10
-rw-r--r--lib/private/files/cache/cache.php16
-rw-r--r--lib/private/files/cache/scanner.php36
-rw-r--r--lib/private/server.php3
-rw-r--r--lib/private/urlgenerator.php18
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 {