summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/base.php34
-rw-r--r--lib/l10n/et_EE.php3
-rw-r--r--lib/private/app.php31
-rw-r--r--lib/private/appframework/core/api.php7
-rw-r--r--lib/private/connector/sabre/file.php13
-rw-r--r--lib/private/eventsource.php93
-rw-r--r--lib/private/files.php2
-rw-r--r--lib/private/files/cache/changepropagator.php8
-rw-r--r--lib/private/files/cache/homecache.php3
-rw-r--r--lib/private/files/cache/updater.php214
-rw-r--r--lib/private/files/view.php65
-rw-r--r--lib/private/helper.php12
-rw-r--r--lib/private/preview/office-cl.php2
-rw-r--r--lib/private/preview/office.php2
-rw-r--r--lib/private/server.php9
-rw-r--r--lib/private/share/constants.php2
-rw-r--r--lib/private/share/share.php5
-rw-r--r--lib/private/template/functions.php18
-rwxr-xr-xlib/private/util.php16
-rw-r--r--lib/public/ieventsource.php34
-rw-r--r--lib/public/iservercontainer.php7
21 files changed, 311 insertions, 269 deletions
diff --git a/lib/base.php b/lib/base.php
index 18331dd86aa..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();
@@ -583,6 +585,21 @@ class OC {
);
return;
}
+
+ $host = OC_Request::insecureServerHost();
+ // if the host passed in headers isn't trusted
+ if (!OC::$CLI
+ // overwritehost is always trusted
+ && OC_Request::getOverwriteHost() === null
+ && !OC_Request::isTrustedDomain($host)
+ ) {
+ header('HTTP/1.1 400 Bad Request');
+ header('Status: 400 Bad Request');
+ $tmpl = new OCP\Template('core', 'untrustedDomain', 'guest');
+ $tmpl->assign('domain', $_SERVER['SERVER_NAME']);
+ $tmpl->printPage();
+ return;
+ }
}
private static function registerLocalAddressBook() {
@@ -683,21 +700,6 @@ class OC {
exit();
}
- $host = OC_Request::insecureServerHost();
- // if the host passed in headers isn't trusted
- if (!OC::$CLI
- // overwritehost is always trusted
- && OC_Request::getOverwriteHost() === null
- && !OC_Request::isTrustedDomain($host)
- ) {
- header('HTTP/1.1 400 Bad Request');
- header('Status: 400 Bad Request');
- $tmpl = new OCP\Template('core', 'untrustedDomain', 'guest');
- $tmpl->assign('domain', $_SERVER['SERVER_NAME']);
- $tmpl->printPage();
- return;
- }
-
$request = OC_Request::getPathInfo();
if (substr($request, -3) !== '.js') { // we need these files during the upgrade
self::checkMaintenanceMode();
diff --git a/lib/l10n/et_EE.php b/lib/l10n/et_EE.php
index 365c2e1f96a..9209d9bb6b3 100644
--- a/lib/l10n/et_EE.php
+++ b/lib/l10n/et_EE.php
@@ -5,6 +5,7 @@ $TRANSLATIONS = array(
"See %s" => "Vaata %s",
"This can usually be fixed by %sgiving the webserver write access to the config directory%s." => "Tavaliselt saab selle lahendada %s andes veebiserverile seadete kataloogile \"config\" kirjutusõigused %s",
"Sample configuration detected" => "Tuvastati näidisseaded",
+"It has been detected that the sample configuration has been copied. This can break your installation and is unsupported. Please read the documentation before performing changes on config.php" => "Tuvastati, et kopeeriti näidisseaded. See võib lõhkuda sinu saidi ja see pole toetatud. Palun loe enne faili config.php muutmist dokumentatsiooni",
"Help" => "Abiinfo",
"Personal" => "Isiklik",
"Settings" => "Seaded",
@@ -65,6 +66,7 @@ $TRANSLATIONS = array(
"Share type %s is not valid for %s" => "Jagamise tüüp %s ei ole õige %s jaoks",
"Setting permissions for %s failed, because the permissions exceed permissions granted to %s" => "Lubade seadistus %s jaoks ebaõnnestus, kuna antud õigused ületavad %s jaoks määratud õigusi",
"Setting permissions for %s failed, because the item was not found" => "Lubade seadistus %s jaoks ebaõnnestus, kuna üksust ei leitud",
+"Cannot set expiration date. Shares cannot expire later than %s after they have been shared" => "Aegumise kuupäeva ei saa määrata. Jagamised ei saa aeguda hiljem kui %s peale jagamist.",
"Cannot set expiration date. Expiration date is in the past" => "Aegumiskuupäeva ei saa määrata. Aegumise kuupäev on minevikus",
"Sharing backend %s must implement the interface OCP\\Share_Backend" => "Jagamise tagarakend %s peab kasutusele võtma OCP\\Share_Backend liidese",
"Sharing backend %s not found" => "Jagamise tagarakendit %s ei leitud",
@@ -97,6 +99,7 @@ $TRANSLATIONS = array(
"Cannot create \"data\" directory (%s)" => "Ei suuda luua \"data\" kataloogi (%s)",
"This can usually be fixed by <a href=\"%s\" target=\"_blank\">giving the webserver write access to the root directory</a>." => "Tavaliselt saab selle lahendada <a href=\"%s\" target=\"_blank\">andes veebiserverile juur-kataloogile kirjutusõigused</a>.",
"Setting locale to %s failed" => "Lokaadi %s määramine ebaõnnestus.",
+"Please install one of these locales on your system and restart your webserver." => "Palun paigalda mõni neist lokaatides oma süsteemi ning taaskäivita veebiserver.",
"Please ask your server administrator to install the module." => "Palu oma serveri haldajal moodul paigadalda.",
"PHP module %s not installed." => "PHP moodulit %s pole paigaldatud.",
"PHP %s or higher is required." => "PHP %s või uuem on nõutav.",
diff --git a/lib/private/app.php b/lib/private/app.php
index d10d352b432..3eed9e3c443 100644
--- a/lib/private/app.php
+++ b/lib/private/app.php
@@ -172,17 +172,29 @@ class OC_App {
*/
protected static $enabledAppsCache = array();
- public static function getEnabledApps($forceRefresh = false) {
+ /**
+ * Returns apps enabled for the current user.
+ *
+ * @param bool $forceRefresh whether to refresh the cache
+ * @param bool $all whether to return apps for all users, not only the
+ * currently logged in one
+ */
+ public static function getEnabledApps($forceRefresh = false, $all = false) {
if (!OC_Config::getValue('installed', false)) {
return array();
}
- if (!$forceRefresh && !empty(self::$enabledAppsCache)) {
+ // in incognito mode or when logged out, $user will be false,
+ // which is also the case during an upgrade
+ $user = null;
+ if (!$all) {
+ $user = \OC_User::getUser();
+ }
+ if (is_string($user) && !$forceRefresh && !empty(self::$enabledAppsCache)) {
return self::$enabledAppsCache;
}
$apps = array();
$appConfig = \OC::$server->getAppConfig();
$appStatus = $appConfig->getValues(false, 'enabled');
- $user = \OC_User::getUser();
foreach ($appStatus as $app => $enabled) {
if ($app === 'files') {
continue;
@@ -192,11 +204,16 @@ class OC_App {
} else if ($enabled !== 'no') {
$groups = json_decode($enabled);
if (is_array($groups)) {
- foreach ($groups as $group) {
- if (\OC_Group::inGroup($user, $group)) {
- $apps[] = $app;
- break;
+ if (is_string($user)) {
+ foreach ($groups as $group) {
+ if (\OC_Group::inGroup($user, $group)) {
+ $apps[] = $app;
+ break;
+ }
}
+ } else {
+ // global, consider app as enabled
+ $apps[] = $app;
}
}
}
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/connector/sabre/file.php b/lib/private/connector/sabre/file.php
index 44c86e69719..5333583e78d 100644
--- a/lib/private/connector/sabre/file.php
+++ b/lib/private/connector/sabre/file.php
@@ -102,13 +102,16 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements \Sabre\
throw new OC_Connector_Sabre_Exception_FileLocked($e->getMessage(), $e->getCode(), $e);
}
+ // if content length is sent by client:
// double check if the file was fully received
// compare expected and actual size
- $expected = $_SERVER['CONTENT_LENGTH'];
- $actual = $this->fileView->filesize($partFilePath);
- if ($actual != $expected) {
- $this->fileView->unlink($partFilePath);
- throw new \Sabre\DAV\Exception\BadRequest('expected filesize ' . $expected . ' got ' . $actual);
+ if (isset($_SERVER['CONTENT_LENGTH'])) {
+ $expected = $_SERVER['CONTENT_LENGTH'];
+ $actual = $this->fileView->filesize($partFilePath);
+ if ($actual != $expected) {
+ $this->fileView->unlink($partFilePath);
+ throw new \Sabre\DAV\Exception\BadRequest('expected filesize ' . $expected . ' got ' . $actual);
+ }
}
// rename to correct path
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/changepropagator.php b/lib/private/files/cache/changepropagator.php
index 30f2e675e2e..2967c8f6259 100644
--- a/lib/private/files/cache/changepropagator.php
+++ b/lib/private/files/cache/changepropagator.php
@@ -57,9 +57,11 @@ class ChangePropagator {
*/
list($storage, $internalPath) = $this->view->resolvePath($parent);
- $cache = $storage->getCache();
- $id = $cache->getId($internalPath);
- $cache->update($id, array('mtime' => $time, 'etag' => $storage->getETag($internalPath)));
+ if ($storage) {
+ $cache = $storage->getCache();
+ $id = $cache->getId($internalPath);
+ $cache->update($id, array('mtime' => $time, 'etag' => $storage->getETag($internalPath)));
+ }
}
}
diff --git a/lib/private/files/cache/homecache.php b/lib/private/files/cache/homecache.php
index 06ae62015a5..2b3967c8807 100644
--- a/lib/private/files/cache/homecache.php
+++ b/lib/private/files/cache/homecache.php
@@ -39,6 +39,9 @@ class HomeCache extends Cache {
$totalSize = 0 + $sum;
$unencryptedSize = 0 + $unencryptedSum;
$entry['size'] += 0;
+ if (!isset($entry['unencrypted_size'])) {
+ $entry['unencrypted_size'] = 0;
+ }
$entry['unencrypted_size'] += 0;
if ($entry['size'] !== $totalSize) {
$this->update($id, array('size' => $totalSize));
diff --git a/lib/private/files/cache/updater.php b/lib/private/files/cache/updater.php
index 0e5e07c587d..c303ff24b1f 100644
--- a/lib/private/files/cache/updater.php
+++ b/lib/private/files/cache/updater.php
@@ -1,6 +1,6 @@
<?php
/**
- * Copyright (c) 2012 Robin Appelman <icewind@owncloud.com>
+ * 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.
@@ -9,165 +9,116 @@
namespace OC\Files\Cache;
/**
- * listen to filesystem hooks and change the cache accordingly
+ * Update the cache and propagate changes
*/
class Updater {
+ /**
+ * @var \OC\Files\View
+ */
+ protected $view;
/**
- * resolve a path to a storage and internal path
- *
- * @param string $path the relative path
- * @return array an array consisting of the storage and the internal path
+ * @var \OC\Files\Cache\ChangePropagator
*/
- static public function resolvePath($path) {
- $view = \OC\Files\Filesystem::getView();
- return $view->resolvePath($path);
+ protected $propagator;
+
+ /**
+ * @param \OC\Files\View $view
+ */
+ public function __construct($view) {
+ $this->view = $view;
+ $this->propagator = new ChangePropagator($view);
}
/**
- * perform a write update
+ * Update the cache for $path
*
- * @param string $path the relative path of the file
+ * @param string $path
+ * @param int $time
*/
- static public function writeUpdate($path) {
+ public function update($path, $time = null) {
/**
* @var \OC\Files\Storage\Storage $storage
* @var string $internalPath
*/
- list($storage, $internalPath) = self::resolvePath($path);
+ list($storage, $internalPath) = $this->view->resolvePath($path);
if ($storage) {
+ $this->propagator->addChange($path);
$cache = $storage->getCache($internalPath);
$scanner = $storage->getScanner($internalPath);
$data = $scanner->scan($internalPath, Scanner::SCAN_SHALLOW);
+ $this->correctParentStorageMtime($storage, $internalPath);
$cache->correctFolderSize($internalPath, $data);
- self::correctFolder($path, $storage->filemtime($internalPath));
- self::correctParentStorageMtime($storage, $internalPath);
+ $this->propagator->propagateChanges($time);
}
}
/**
- * perform a delete update
+ * Remove $path from the cache
*
- * @param string $path the relative path of the file
+ * @param string $path
*/
- static public function deleteUpdate($path) {
+ public function remove($path) {
/**
* @var \OC\Files\Storage\Storage $storage
* @var string $internalPath
*/
- list($storage, $internalPath) = self::resolvePath($path);
+ list($storage, $internalPath) = $this->view->resolvePath($path);
if ($storage) {
$parent = dirname($internalPath);
if ($parent === '.') {
$parent = '';
}
+ $this->propagator->addChange($path);
$cache = $storage->getCache($internalPath);
$cache->remove($internalPath);
$cache->correctFolderSize($parent);
- self::correctFolder($path, time());
- self::correctParentStorageMtime($storage, $internalPath);
+ $this->correctParentStorageMtime($storage, $internalPath);
+ $this->propagator->propagateChanges();
}
}
/**
- * preform a rename update
- *
- * @param string $from the relative path of the source file
- * @param string $to the relative path of the target file
+ * @param string $source
+ * @param string $target
*/
- static public function renameUpdate($from, $to) {
+ public function rename($source, $target) {
/**
- * @var \OC\Files\Storage\Storage $storageFrom
- * @var \OC\Files\Storage\Storage $storageTo
- * @var string $internalFrom
- * @var string $internalTo
+ * @var \OC\Files\Storage\Storage $sourceStorage
+ * @var \OC\Files\Storage\Storage $targetStorage
+ * @var string $sourceInternalPath
+ * @var string $targetInternalPath
*/
- list($storageFrom, $internalFrom) = self::resolvePath($from);
+ list($sourceStorage, $sourceInternalPath) = $this->view->resolvePath($source);
// if it's a moved mountpoint we dont need to do anything
- if ($internalFrom === '') {
+ if ($sourceInternalPath === '') {
return;
}
- list($storageTo, $internalTo) = self::resolvePath($to);
- if ($storageFrom && $storageTo) {
- if ($storageFrom === $storageTo) {
- $cache = $storageFrom->getCache($internalFrom);
- $cache->move($internalFrom, $internalTo);
- if (pathinfo($internalFrom, PATHINFO_EXTENSION) !== pathinfo($internalTo, PATHINFO_EXTENSION)) {
- // redetect mime type change
- $mimeType = $storageTo->getMimeType($internalTo);
- $fileId = $storageTo->getCache()->getId($internalTo);
- $storageTo->getCache()->update($fileId, array('mimetype' => $mimeType));
+ list($targetStorage, $targetInternalPath) = $this->view->resolvePath($target);
+
+ if ($sourceStorage && $targetStorage) {
+ if ($sourceStorage === $targetStorage) {
+ $cache = $sourceStorage->getCache($sourceInternalPath);
+ $cache->move($sourceInternalPath, $targetInternalPath);
+
+ if (pathinfo($sourceInternalPath, PATHINFO_EXTENSION) !== pathinfo($targetInternalPath, PATHINFO_EXTENSION)) {
+ // handle mime type change
+ $mimeType = $sourceStorage->getMimeType($targetInternalPath);
+ $fileId = $cache->getId($targetInternalPath);
+ $cache->update($fileId, array('mimetype' => $mimeType));
}
- $cache->correctFolderSize($internalFrom);
- $cache->correctFolderSize($internalTo);
- self::correctFolder($from, time());
- self::correctFolder($to, time());
- self::correctParentStorageMtime($storageFrom, $internalFrom);
- self::correctParentStorageMtime($storageTo, $internalTo);
- } else {
- self::deleteUpdate($from);
- self::writeUpdate($to);
- }
- }
- }
- /**
- * get file owner and path
- * @param string $filename
- * @return string[] with the owner's uid and the owner's path
- */
- private static function getUidAndFilename($filename) {
-
- $uid = \OC\Files\Filesystem::getOwner($filename);
- \OC\Files\Filesystem::initMountPoints($uid);
-
- $filename = (strpos($filename, '/') !== 0) ? '/' . $filename : $filename;
- if ($uid != \OCP\User::getUser()) {
- $info = \OC\Files\Filesystem::getFileInfo($filename);
- if (!$info) {
- return array($uid, '/files' . $filename);
- }
- $ownerView = new \OC\Files\View('/' . $uid . '/files');
- $filename = $ownerView->getPath($info['fileid']);
- }
- return array($uid, '/files' . $filename);
- }
-
- /**
- * Update the mtime and ETag of all parent folders
- *
- * @param string $path
- * @param string $time
- */
- static public function correctFolder($path, $time) {
- if ($path !== '' && $path !== '/' && $path !== '\\') {
- list($owner, $realPath) = self::getUidAndFilename(dirname($path));
-
- /**
- * @var \OC\Files\Storage\Storage $storage
- * @var string $internalPath
- */
- $view = new \OC\Files\View('/' . $owner);
-
- list($storage, $internalPath) = $view->resolvePath($realPath);
- $cache = $storage->getCache();
- $id = $cache->getId($internalPath);
-
- while ($id !== -1) {
- $cache->update($id, array('mtime' => $time, 'etag' => $storage->getETag($internalPath)));
- if ($realPath !== '') {
- $realPath = dirname($realPath);
- if ($realPath === DIRECTORY_SEPARATOR) {
- $realPath = "";
- }
- // check storage for parent in case we change the storage in this step
- list($storage, $internalPath) = $view->resolvePath($realPath);
- $cache = $storage->getCache();
- $id = $cache->getId($internalPath);
- } else {
- $id = -1;
- }
+ $cache->correctFolderSize($sourceInternalPath);
+ $cache->correctFolderSize($targetInternalPath);
+ $this->correctParentStorageMtime($sourceStorage, $sourceInternalPath);
+ $this->correctParentStorageMtime($targetStorage, $targetInternalPath);
+ $this->propagator->addChange($source);
+ $this->propagator->addChange($target);
+ } else {
+ $this->remove($source);
+ $this->update($target);
}
+ $this->propagator->propagateChanges();
}
}
@@ -177,52 +128,17 @@ class Updater {
* @param \OC\Files\Storage\Storage $storage
* @param string $internalPath
*/
- static private function correctParentStorageMtime($storage, $internalPath) {
+ private function correctParentStorageMtime($storage, $internalPath) {
$cache = $storage->getCache();
$parentId = $cache->getParentId($internalPath);
$parent = dirname($internalPath);
-
- if ($parent === '.' || $parent === '/' || $parent === '\\') {
- $parent = '';
- }
-
if ($parentId != -1) {
$cache->update($parentId, array('storage_mtime' => $storage->filemtime($parent)));
}
}
- /**
- * @param array $params
- */
- static public function writeHook($params) {
- self::writeUpdate($params['path']);
- }
-
- /**
- * @param array $params
- */
- static public function touchHook($params) {
- $path = $params['path'];
- list($storage, $internalPath) = self::resolvePath($path);
- $cache = $storage->getCache();
- $id = $cache->getId($internalPath);
- if ($id !== -1) {
- $cache->update($id, array('etag' => $storage->getETag($internalPath)));
- }
- self::writeUpdate($path);
- }
-
- /**
- * @param array $params
- */
- static public function renameHook($params) {
- self::renameUpdate($params['oldpath'], $params['newpath']);
- }
-
- /**
- * @param array $params
- */
- static public function deleteHook($params) {
- self::deleteUpdate($params['path']);
+ public function __destruct() {
+ // propagate any leftover changes
+ $this->propagator->propagateChanges();
}
}
diff --git a/lib/private/files/view.php b/lib/private/files/view.php
index d310a0fa4e1..95f3e9a2c7f 100644
--- a/lib/private/files/view.php
+++ b/lib/private/files/view.php
@@ -31,8 +31,14 @@ use OC\Files\Mount\MoveableMount;
class View {
private $fakeRoot = '';
+ /**
+ * @var \OC\Files\Cache\Updater
+ */
+ protected $updater;
+
public function __construct($root = '') {
$this->fakeRoot = $root;
+ $this->updater = new Updater($this);
}
public function getAbsolutePath($path = '/') {
@@ -168,10 +174,10 @@ class View {
* @param string $path relative to data/
* @return boolean
*/
- protected function removeMount($mount, $path){
+ protected function removeMount($mount, $path) {
if ($mount instanceof MoveableMount) {
// cut of /user/files to get the relative path to data/user/files
- $pathParts= explode('/', $path, 4);
+ $pathParts = explode('/', $path, 4);
$relPath = '/' . $pathParts[3];
\OC_Hook::emit(
Filesystem::CLASSNAME, "umount",
@@ -194,7 +200,7 @@ class View {
}
public function rmdir($path) {
- $absolutePath= $this->getAbsolutePath($path);
+ $absolutePath = $this->getAbsolutePath($path);
$mount = Filesystem::getMountManager()->find($absolutePath);
if ($mount->getInternalPath($absolutePath) === '') {
return $this->removeMount($mount, $path);
@@ -304,7 +310,16 @@ class View {
$hooks[] = 'write';
}
$result = $this->basicOperation('touch', $path, $hooks, $mtime);
- if (!$result) { //if native touch fails, we emulate it by changing the mtime in the cache
+ if (!$result) {
+ // If create file fails because of permissions on external storage like SMB folders,
+ // check file exists and return false if not.
+ if(!$this->file_exists($path)){
+ return false;
+ }
+ if (is_null($mtime)) {
+ $mtime = time();
+ }
+ //if native touch fails, we emulate it by changing the mtime in the cache
$this->putFileInfo($path, array('mtime' => $mtime));
}
return true;
@@ -368,10 +383,8 @@ class View {
list ($count, $result) = \OC_Helper::streamCopy($data, $target);
fclose($target);
fclose($data);
+ $this->updater->update($path);
if ($this->shouldEmitHooks($path) && $result !== false) {
- Updater::writeHook(array(
- 'path' => $this->getHookPath($path)
- ));
$this->emit_file_hooks_post($exists, $path);
}
\OC_FileProxy::runPostProxies('file_put_contents', $absolutePath, $count);
@@ -396,7 +409,7 @@ class View {
$postFix = (substr($path, -1, 1) === '/') ? '/' : '';
$absolutePath = Filesystem::normalizePath($this->getAbsolutePath($path));
$mount = Filesystem::getMountManager()->find($absolutePath . $postFix);
- if ($mount->getInternalPath($absolutePath) === '') {
+ if ($mount and $mount->getInternalPath($absolutePath) === '') {
return $this->removeMount($mount, $absolutePath);
}
return $this->basicOperation('unlink', $path, array('delete'));
@@ -489,15 +502,14 @@ class View {
}
}
}
- if ($this->shouldEmitHooks() && (Cache\Scanner::isPartialFile($path1) && !Cache\Scanner::isPartialFile($path2)) && $result !== false) {
+ if ((Cache\Scanner::isPartialFile($path1) && !Cache\Scanner::isPartialFile($path2)) && $result !== false) {
// if it was a rename from a part file to a regular file it was a write and not a rename operation
- Updater::writeHook(array('path' => $this->getHookPath($path2)));
- $this->emit_file_hooks_post($exists, $path2);
+ $this->updater->update($path2);
+ if ($this->shouldEmitHooks()) {
+ $this->emit_file_hooks_post($exists, $path2);
+ }
} elseif ($this->shouldEmitHooks() && $result !== false) {
- Updater::renameHook(array(
- 'oldpath' => $this->getHookPath($path1),
- 'newpath' => $this->getHookPath($path2)
- ));
+ $this->updater->rename($path1, $path2);
\OC_Hook::emit(
Filesystem::CLASSNAME,
Filesystem::signal_post_rename,
@@ -576,6 +588,7 @@ class View {
fclose($target);
}
}
+ $this->updater->update($path2);
if ($this->shouldEmitHooks() && $result !== false) {
\OC_Hook::emit(
Filesystem::CLASSNAME,
@@ -754,7 +767,19 @@ class View {
} else {
$result = $storage->$operation($internalPath);
}
+
$result = \OC_FileProxy::runPostProxies($operation, $this->getAbsolutePath($path), $result);
+
+ if (in_array('delete', $hooks)) {
+ $this->updater->remove($path);
+ }
+ if (in_array('write', $hooks)) {
+ $this->updater->update($path);
+ }
+ if (in_array('touch', $hooks)) {
+ $this->updater->update($path, $extraParam);
+ }
+
if ($this->shouldEmitHooks($path) && $result !== false) {
if ($operation != 'fopen') { //no post hooks for fopen, the file stream is still open
$this->runHooks($hooks, $path, true);
@@ -808,16 +833,6 @@ class View {
$run = true;
if ($this->shouldEmitHooks($path)) {
foreach ($hooks as $hook) {
- // manually triger updater hooks to ensure they are called first
- if ($post) {
- if ($hook == 'write') {
- Updater::writeHook(array('path' => $path));
- } elseif ($hook == 'touch') {
- Updater::touchHook(array('path' => $path));
- } else if ($hook == 'delete') {
- Updater::deleteHook(array('path' => $path));
- }
- }
if ($hook != 'read') {
\OC_Hook::emit(
Filesystem::CLASSNAME,
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/preview/office.php b/lib/private/preview/office.php
index 16e395cb1a8..b47cbc6e08f 100644
--- a/lib/private/preview/office.php
+++ b/lib/private/preview/office.php
@@ -17,7 +17,7 @@ if (extension_loaded('imagick')) {
if (!\OC_Util::runningOnWindows()) {
$whichLibreOffice = ($isShellExecEnabled ? shell_exec('command -v libreoffice') : '');
$isLibreOfficeAvailable = !empty($whichLibreOffice);
- $whichOpenOffice = ($isShellExecEnabled ? shell_exec('command -v libreoffice') : '');
+ $whichOpenOffice = ($isShellExecEnabled ? shell_exec('command -v openoffice') : '');
$isOpenOfficeAvailable = !empty($whichOpenOffice);
//let's see if there is libreoffice or openoffice on this machine
if($isShellExecEnabled && ($isLibreOfficeAvailable || $isOpenOfficeAvailable || is_string(\OC_Config::getValue('preview_libreoffice_path', null)))) {
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/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..09db011e748 100644
--- a/lib/private/template/functions.php
+++ b/lib/private/template/functions.php
@@ -24,6 +24,24 @@ function print_unescaped($string) {
}
/**
+ * Shortcut for adding scripts to a page
+ * @param string $app the appname
+ * @param string $file the filename
+ */
+function script($app, $file) {
+ OC_Util::addScript($app, $file);
+}
+
+/**
+ * Shortcut for adding styles to a page
+ * @param string $app the appname
+ * @param string $file the filename
+ */
+function style($app, $file) {
+ OC_Util::addStyle($app, $file);
+}
+
+/**
* 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 2a0f9197e3c..6f45e00215d 100755
--- a/lib/private/util.php
+++ b/lib/private/util.php
@@ -1461,9 +1461,11 @@ class OC_Util {
}
/**
- * Check whether the instance needs to preform an upgrade
+ * Check whether the instance needs to perform an upgrade,
+ * either when the core version is higher or any app requires
+ * an upgrade.
*
- * @return bool
+ * @return bool whether the core or any app needs an upgrade
*/
public static function needUpgrade() {
if (OC_Config::getValue('installed', false)) {
@@ -1473,14 +1475,16 @@ class OC_Util {
return true;
}
- // also check for upgrades for apps
- $apps = \OC_App::getEnabledApps();
+ // also check for upgrades for apps (independently from the user)
+ $apps = \OC_App::getEnabledApps(false, true);
+ $shouldUpgrade = false;
foreach ($apps as $app) {
if (\OC_App::shouldUpgrade($app)) {
- return true;
+ $shouldUpgrade = true;
+ break;
}
}
- return false;
+ return $shouldUpgrade;
} else {
return false;
}
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();
}