summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--apps/files/ajax/list.php69
-rw-r--r--apps/files/js/filelist.js23
-rw-r--r--apps/files_sharing/css/public.css14
-rw-r--r--apps/files_sharing/js/external.js2
-rw-r--r--apps/files_sharing/js/public.js1
-rw-r--r--apps/files_sharing/lib/external/manager.php2
-rw-r--r--apps/files_sharing/lib/external/scanner.php18
-rw-r--r--apps/files_sharing/lib/external/storage.php85
-rw-r--r--apps/files_sharing/templates/public.php2
-rw-r--r--apps/files_sharing/tests/externalstorage.php1
-rw-r--r--core/css/mobile.css14
-rw-r--r--lib/private/appframework/http/dispatcher.php2
-rw-r--r--lib/private/connector/sabre/objecttree.php10
-rw-r--r--lib/private/files/mount/manager.php4
-rw-r--r--lib/private/files/storage/dav.php44
-rw-r--r--lib/public/files/storageinvalidexception.php22
-rw-r--r--lib/public/files/storagenotavailableexception.php22
-rw-r--r--public.php2
18 files changed, 249 insertions, 88 deletions
diff --git a/apps/files/ajax/list.php b/apps/files/ajax/list.php
index bae3628402f..b4641343ed4 100644
--- a/apps/files/ajax/list.php
+++ b/apps/files/ajax/list.php
@@ -2,29 +2,54 @@
OCP\JSON::checkLoggedIn();
\OC::$session->close();
+$l = OC_L10N::get('files');
// Load the files
-$dir = isset( $_GET['dir'] ) ? $_GET['dir'] : '';
+$dir = isset($_GET['dir']) ? $_GET['dir'] : '';
$dir = \OC\Files\Filesystem::normalizePath($dir);
-$dirInfo = \OC\Files\Filesystem::getFileInfo($dir);
-if (!$dirInfo || !$dirInfo->getType() === 'dir') {
- header("HTTP/1.0 404 Not Found");
- exit();
-}
-
-$data = array();
-$baseUrl = OCP\Util::linkTo('files', 'index.php') . '?dir=';
-
-$permissions = $dirInfo->getPermissions();
-
-$sortAttribute = isset( $_GET['sort'] ) ? $_GET['sort'] : 'name';
-$sortDirection = isset( $_GET['sortdirection'] ) ? ($_GET['sortdirection'] === 'desc') : false;
-// make filelist
-$files = \OCA\Files\Helper::getFiles($dir, $sortAttribute, $sortDirection);
-
-$data['directory'] = $dir;
-$data['files'] = \OCA\Files\Helper::formatFileInfos($files);
-$data['permissions'] = $permissions;
-
-OCP\JSON::success(array('data' => $data));
+try {
+ $dirInfo = \OC\Files\Filesystem::getFileInfo($dir);
+ if (!$dirInfo || !$dirInfo->getType() === 'dir') {
+ header("HTTP/1.0 404 Not Found");
+ exit();
+ }
+
+ $data = array();
+ $baseUrl = OCP\Util::linkTo('files', 'index.php') . '?dir=';
+
+ $permissions = $dirInfo->getPermissions();
+
+ $sortAttribute = isset($_GET['sort']) ? $_GET['sort'] : 'name';
+ $sortDirection = isset($_GET['sortdirection']) ? ($_GET['sortdirection'] === 'desc') : false;
+
+ // make filelist
+
+ $files = \OCA\Files\Helper::getFiles($dir, $sortAttribute, $sortDirection);
+ $data['directory'] = $dir;
+ $data['files'] = \OCA\Files\Helper::formatFileInfos($files);
+ $data['permissions'] = $permissions;
+
+ OCP\JSON::success(array('data' => $data));
+} catch (\OCP\Files\StorageNotAvailableException $e) {
+ OCP\JSON::error(array(
+ 'data' => array(
+ 'exception' => '\OCP\Files\StorageNotAvailableException',
+ 'message' => $l->t('Storage not available')
+ )
+ ));
+} catch (\OCP\Files\StorageInvalidException $e) {
+ OCP\JSON::error(array(
+ 'data' => array(
+ 'exception' => '\OCP\Files\StorageInvalidException',
+ 'message' => $l->t('Storage invalid')
+ )
+ ));
+} catch (\Exception $e) {
+ OCP\JSON::error(array(
+ 'data' => array(
+ 'exception' => '\Exception',
+ 'message' => $l->t('Unknown error')
+ )
+ ));
+}
diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js
index c7fccc5dd66..94f161943a1 100644
--- a/apps/files/js/filelist.js
+++ b/apps/files/js/filelist.js
@@ -846,13 +846,18 @@
* @param {boolean} force set to true to force changing directory
*/
changeDirectory: function(targetDir, changeUrl, force) {
+ var self = this;
var currentDir = this.getCurrentDirectory();
targetDir = targetDir || '/';
if (!force && currentDir === targetDir) {
return;
}
this._setCurrentDir(targetDir, changeUrl);
- this.reload();
+ this.reload().then(function(success){
+ if (!success) {
+ self.changeDirectory(currentDir, true);
+ }
+ });
},
linkTo: function(dir) {
return OC.linkTo('files', 'index.php')+"?dir="+ encodeURIComponent(dir).replace(/%2F/g, '/');
@@ -912,7 +917,6 @@
* @brief Reloads the file list using ajax call
*/
reload: function() {
- var self = this;
this._selectedFiles = {};
this._selectionSummary.clear();
this.$el.find('.select-all').prop('checked', false);
@@ -926,14 +930,10 @@
dir : this.getCurrentDirectory(),
sort: this._sort,
sortdirection: this._sortDirection
- },
- error: function(result) {
- self.reloadCallback(result);
- },
- success: function(result) {
- self.reloadCallback(result);
}
});
+ var callBack = this.reloadCallback.bind(this);
+ return this._reloadCall.then(callBack, callBack);
},
reloadCallback: function(result) {
delete this._reloadCall;
@@ -941,17 +941,17 @@
if (!result || result.status === 'error') {
OC.Notification.show(result.data.message);
- return;
+ return false;
}
if (result.status === 404) {
// go back home
this.changeDirectory('/');
- return;
+ return false;
}
// aborted ?
if (result.status === 0){
- return;
+ return true;
}
// TODO: should rather return upload file size through
@@ -963,6 +963,7 @@
}
this.setFiles(result.data.files);
+ return true
},
updateStorageStatistics: function(force) {
diff --git a/apps/files_sharing/css/public.css b/apps/files_sharing/css/public.css
index 31c3bca8748..ddd9d10d664 100644
--- a/apps/files_sharing/css/public.css
+++ b/apps/files_sharing/css/public.css
@@ -88,20 +88,6 @@ thead {
max-width: 90%;
}
-.header-right {
- transition: opacity 500ms ease 0s;
- -moz-transition: opacity 500ms ease 0s;
- -ms-transition: opacity 500ms ease 0s;
- -o-transition: opacity 500ms ease 0s;
- -webkit-transition: opacity 500ms ease 0s;
-}
-
-.header-right:hover, .header-right.active {
- opacity: 1;
- -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)";
- filter: alpha(opacity=100);
-}
-
/* within #save */
#remote_address {
margin: 0;
diff --git a/apps/files_sharing/js/external.js b/apps/files_sharing/js/external.js
index 1eb447da896..969a2b184d4 100644
--- a/apps/files_sharing/js/external.js
+++ b/apps/files_sharing/js/external.js
@@ -58,7 +58,7 @@ $(document).ready(function () {
if (params.remote && params.token && params.owner && params.name) {
// clear hash, it is unlikely that it contain any extra parameters
location.hash = '';
- params.passwordProtected = parseInt(params.passwordProtected, 10) === 1;
+ params.passwordProtected = parseInt(params.protected, 10) === 1;
OCA.Sharing.showAddExternalDialog(
params.remote,
params.token,
diff --git a/apps/files_sharing/js/public.js b/apps/files_sharing/js/public.js
index f911f3689eb..a5027da0cfb 100644
--- a/apps/files_sharing/js/public.js
+++ b/apps/files_sharing/js/public.js
@@ -165,7 +165,6 @@ OCA.Sharing.PublicApp = {
$('#save > button').click(function () {
$(this).hide();
- $('.header-right').addClass('active');
$('.save-form').css('display', 'inline');
$('#remote_address').focus();
});
diff --git a/apps/files_sharing/lib/external/manager.php b/apps/files_sharing/lib/external/manager.php
index af317cc2027..dda283f4952 100644
--- a/apps/files_sharing/lib/external/manager.php
+++ b/apps/files_sharing/lib/external/manager.php
@@ -113,7 +113,9 @@ class Manager {
* @return Mount
*/
protected function mountShare($data) {
+ $data['manager'] = $this;
$mountPoint = '/' . $this->userSession->getUser()->getUID() . '/files' . $data['mountpoint'];
+ $data['mountpoint'] = $mountPoint;
$mount = new Mount(self::STORAGE, $mountPoint, $data, $this, $this->storageLoader);
$this->mountManager->addMount($mount);
return $mount;
diff --git a/apps/files_sharing/lib/external/scanner.php b/apps/files_sharing/lib/external/scanner.php
index 8921dd1a4c0..4dc5d4be9d8 100644
--- a/apps/files_sharing/lib/external/scanner.php
+++ b/apps/files_sharing/lib/external/scanner.php
@@ -19,23 +19,7 @@ class Scanner extends \OC\Files\Cache\Scanner {
}
public function scanAll() {
- $remote = $this->storage->getRemote();
- $token = $this->storage->getToken();
- $password = $this->storage->getPassword();
- $url = $remote . '/index.php/apps/files_sharing/shareinfo?t=' . $token;
-
- $ch = curl_init();
-
- curl_setopt($ch, CURLOPT_URL, $url);
- curl_setopt($ch, CURLOPT_POST, 1);
- curl_setopt($ch, CURLOPT_POSTFIELDS,
- http_build_query(array('password' => $password)));
- curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
-
- $result = curl_exec($ch);
- curl_close($ch);
-
- $data = json_decode($result, true);
+ $data = $this->storage->getShareInfo();
if ($data['status'] === 'success') {
$this->addResult($data['data'], '');
} else {
diff --git a/apps/files_sharing/lib/external/storage.php b/apps/files_sharing/lib/external/storage.php
index 454196f15ae..3a0de51192e 100644
--- a/apps/files_sharing/lib/external/storage.php
+++ b/apps/files_sharing/lib/external/storage.php
@@ -10,7 +10,11 @@ namespace OCA\Files_Sharing\External;
use OC\Files\Filesystem;
use OC\Files\Storage\DAV;
+use OC\ForbiddenException;
use OCA\Files_Sharing\ISharedStorage;
+use OCP\Files\NotFoundException;
+use OCP\Files\StorageInvalidException;
+use OCP\Files\StorageNotAvailableException;
class Storage extends DAV implements ISharedStorage {
/**
@@ -35,7 +39,13 @@ class Storage extends DAV implements ISharedStorage {
private $updateChecked = false;
+ /**
+ * @var \OCA\Files_Sharing\External\Manager
+ */
+ private $manager;
+
public function __construct($options) {
+ $this->manager = $options['manager'];
$this->remote = $options['remote'];
$this->remoteUser = $options['owner'];
list($protocol, $remote) = explode('://', $this->remote);
@@ -108,6 +118,8 @@ class Storage extends DAV implements ISharedStorage {
*
* @param string $path
* @param int $time
+ * @throws \OCP\Files\StorageNotAvailableException
+ * @throws \OCP\Files\StorageInvalidException
* @return bool
*/
public function hasUpdated($path, $time) {
@@ -117,6 +129,77 @@ class Storage extends DAV implements ISharedStorage {
return false;
}
$this->updateChecked = true;
- return parent::hasUpdated('', $time);
+ try {
+ return parent::hasUpdated('', $time);
+ } catch (StorageNotAvailableException $e) {
+ // see if we can find out why the share is unavailable\
+ try {
+ $this->getShareInfo();
+ } catch (NotFoundException $shareException) {
+ // a 404 can either mean that the share no longer exists or there is no ownCloud on the remote
+ if ($this->testRemote()) {
+ // valid ownCloud instance means that the public share no longer exists
+ // since this is permanent (re-sharing the file will create a new token)
+ // we remove the invalid storage
+ $this->manager->removeShare($this->mountPoint);
+ $this->manager->getMountManager()->removeMount($this->mountPoint);
+ throw new StorageInvalidException();
+ } else {
+ // ownCloud instance is gone, likely to be a temporary server configuration error
+ throw $e;
+ }
+ } catch(\Exception $shareException) {
+ // todo, maybe handle 403 better and ask the user for a new password
+ throw $e;
+ }
+ throw $e;
+ }
+ }
+
+ /**
+ * check if the configured remote is a valid ownCloud instance
+ *
+ * @return bool
+ */
+ protected function testRemote() {
+ try {
+ $result = file_get_contents($this->remote . '/status.php');
+ $data = json_decode($result);
+ return is_object($data) and !empty($data->version);
+ } catch (\Exception $e) {
+ return false;
+ }
+ }
+
+ public function getShareInfo() {
+ $remote = $this->getRemote();
+ $token = $this->getToken();
+ $password = $this->getPassword();
+ $url = $remote . '/index.php/apps/files_sharing/shareinfo?t=' . $token;
+
+ $ch = curl_init();
+
+ curl_setopt($ch, CURLOPT_URL, $url);
+ curl_setopt($ch, CURLOPT_POST, 1);
+ curl_setopt($ch, CURLOPT_POSTFIELDS,
+ http_build_query(array('password' => $password)));
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+
+ $result = curl_exec($ch);
+
+ $status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
+ curl_close($ch);
+
+ switch ($status) {
+ case 401:
+ case 403:
+ throw new ForbiddenException();
+ case 404:
+ throw new NotFoundException();
+ case 500:
+ throw new \Exception();
+ }
+
+ return json_decode($result, true);
}
}
diff --git a/apps/files_sharing/templates/public.php b/apps/files_sharing/templates/public.php
index c053aaabece..65e620a3425 100644
--- a/apps/files_sharing/templates/public.php
+++ b/apps/files_sharing/templates/public.php
@@ -17,7 +17,7 @@
<div class="header-right">
<span id="details">
<span id="save" data-protected="<?php p($_['protected'])?>" data-owner="<?php p($_['displayName'])?>" data-name="<?php p($_['filename'])?>">
- <button><?php p($l->t('Save to ownCloud')) ?></button>
+ <button><?php p($l->t('Add to your ownCloud')) ?></button>
<form class="save-form hidden" action="#">
<input type="text" id="remote_address" placeholder="<?php p($l->t('example.com/owncloud')) ?>"/>
<input type="submit" value="<?php p($l->t('Save')) ?>"/>
diff --git a/apps/files_sharing/tests/externalstorage.php b/apps/files_sharing/tests/externalstorage.php
index 60c5787f295..1258148af53 100644
--- a/apps/files_sharing/tests/externalstorage.php
+++ b/apps/files_sharing/tests/externalstorage.php
@@ -72,6 +72,7 @@ class Test_Files_Sharing_External_Storage extends \PHPUnit_Framework_TestCase {
'mountpoint' => 'remoteshare',
'token' => 'abcdef',
'password' => '',
+ 'manager' => null
)
);
$this->assertEquals($baseUri, $storage->getBaseUri());
diff --git a/core/css/mobile.css b/core/css/mobile.css
index 2003e0a7f45..bdca29d888a 100644
--- a/core/css/mobile.css
+++ b/core/css/mobile.css
@@ -82,6 +82,11 @@
background-color: #fff;
overflow-x: hidden !important;
}
+/* allow horizontal scrollbar in settings
+ otherwise user management is not usable on mobile */
+#body-settings #app-content {
+ overflow-x: auto !important;
+}
#app-navigation-toggle {
position: fixed;
@@ -129,6 +134,15 @@ table.multiselect thead {
}
+/* prevent overflow in user management controls bar */
+#usersearchform {
+ display: none;
+}
+#body-settings #controls {
+ min-width: 768px !important;
+}
+
+
/* fix controls bar jumping when navigation is slid out */
.snapjs-left #app-navigation-toggle,
.snapjs-left #controls {
diff --git a/lib/private/appframework/http/dispatcher.php b/lib/private/appframework/http/dispatcher.php
index fa8d3c47a8b..7f2717951a5 100644
--- a/lib/private/appframework/http/dispatcher.php
+++ b/lib/private/appframework/http/dispatcher.php
@@ -145,7 +145,7 @@ class Dispatcher {
) {
$value = false;
- } elseif(in_array($type, $types)) {
+ } elseif($value !== null && in_array($type, $types)) {
settype($value, $type);
}
diff --git a/lib/private/connector/sabre/objecttree.php b/lib/private/connector/sabre/objecttree.php
index 54596db3c47..d7a96cfc88e 100644
--- a/lib/private/connector/sabre/objecttree.php
+++ b/lib/private/connector/sabre/objecttree.php
@@ -11,6 +11,8 @@ namespace OC\Connector\Sabre;
use OC\Files\FileInfo;
use OC\Files\Filesystem;
use OC\Files\Mount\MoveableMount;
+use OCP\Files\StorageInvalidException;
+use OCP\Files\StorageNotAvailableException;
class ObjectTree extends \Sabre\DAV\ObjectTree {
@@ -83,7 +85,13 @@ class ObjectTree extends \Sabre\DAV\ObjectTree {
}
} else {
// read from cache
- $info = $this->fileView->getFileInfo($path);
+ try {
+ $info = $this->fileView->getFileInfo($path);
+ } catch (StorageNotAvailableException $e) {
+ throw new \Sabre\DAV\Exception\ServiceUnavailable('Storage not available');
+ } catch (StorageInvalidException $e){
+ throw new \Sabre\DAV\Exception\NotFound('Storage ' . $path . ' is invalid');
+ }
}
if (!$info) {
diff --git a/lib/private/files/mount/manager.php b/lib/private/files/mount/manager.php
index 45a9f339fba..e5180cfe173 100644
--- a/lib/private/files/mount/manager.php
+++ b/lib/private/files/mount/manager.php
@@ -27,6 +27,10 @@ class Manager {
* @param string $mountPoint
*/
public function removeMount($mountPoint) {
+ $mountPoint = Filesystem::normalizePath($mountPoint);
+ if (strlen($mountPoint) > 1) {
+ $mountPoint .= '/';
+ }
unset($this->mounts[$mountPoint]);
}
diff --git a/lib/private/files/storage/dav.php b/lib/private/files/storage/dav.php
index 8b97f750204..726688fe444 100644
--- a/lib/private/files/storage/dav.php
+++ b/lib/private/files/storage/dav.php
@@ -8,6 +8,9 @@
namespace OC\Files\Storage;
+use OCP\Files\StorageNotAvailableException;
+use Sabre\DAV\Exception;
+
class DAV extends \OC\Files\Storage\Common {
protected $password;
protected $user;
@@ -463,29 +466,36 @@ class DAV extends \OC\Files\Storage\Common {
*
* @param string $path
* @param int $time
+ * @throws \OCP\Files\StorageNotAvailableException
* @return bool
*/
public function hasUpdated($path, $time) {
$this->init();
- $response = $this->client->propfind($this->encodePath($path), array(
- '{DAV:}getlastmodified',
- '{DAV:}getetag',
- '{http://owncloud.org/ns}permissions'
- ));
- if (isset($response['{DAV:}getetag'])) {
- $cachedData = $this->getCache()->get($path);
- $etag = trim($response['{DAV:}getetag'], '"');
- if ($cachedData['etag'] !== $etag) {
- return true;
- } else if (isset($response['{http://owncloud.org/ns}permissions'])) {
- $permissions = $this->parsePermissions($response['{http://owncloud.org/ns}permissions']);
- return $permissions !== $cachedData['permissions'];
+ try {
+ $response = $this->client->propfind($this->encodePath($path), array(
+ '{DAV:}getlastmodified',
+ '{DAV:}getetag',
+ '{http://owncloud.org/ns}permissions'
+ ));
+ if (isset($response['{DAV:}getetag'])) {
+ $cachedData = $this->getCache()->get($path);
+ $etag = trim($response['{DAV:}getetag'], '"');
+ if ($cachedData['etag'] !== $etag) {
+ return true;
+ } else if (isset($response['{http://owncloud.org/ns}permissions'])) {
+ $permissions = $this->parsePermissions($response['{http://owncloud.org/ns}permissions']);
+ return $permissions !== $cachedData['permissions'];
+ } else {
+ return false;
+ }
} else {
- return false;
+ $remoteMtime = strtotime($response['{DAV:}getlastmodified']);
+ return $remoteMtime > $time;
}
- } else {
- $remoteMtime = strtotime($response['{DAV:}getlastmodified']);
- return $remoteMtime > $time;
+ } catch (Exception\NotFound $e) {
+ return false;
+ } catch (Exception $e) {
+ throw new StorageNotAvailableException();
}
}
}
diff --git a/lib/public/files/storageinvalidexception.php b/lib/public/files/storageinvalidexception.php
new file mode 100644
index 00000000000..7419ccc1d11
--- /dev/null
+++ b/lib/public/files/storageinvalidexception.php
@@ -0,0 +1,22 @@
+<?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.
+ */
+
+/**
+ * Public interface of ownCloud for apps to use.
+ * Files/AlreadyExistsException class
+ */
+
+// use OCP namespace for all classes that are considered public.
+// This means that they should be used by apps instead of the internal ownCloud classes
+namespace OCP\Files;
+
+/**
+ * Storage has invalid configuration
+ */
+class StorageInvalidException extends \Exception {
+}
diff --git a/lib/public/files/storagenotavailableexception.php b/lib/public/files/storagenotavailableexception.php
new file mode 100644
index 00000000000..b526cb4ea0f
--- /dev/null
+++ b/lib/public/files/storagenotavailableexception.php
@@ -0,0 +1,22 @@
+<?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.
+ */
+
+/**
+ * Public interface of ownCloud for apps to use.
+ * Files/AlreadyExistsException class
+ */
+
+// use OCP namespace for all classes that are considered public.
+// This means that they should be used by apps instead of the internal ownCloud classes
+namespace OCP\Files;
+
+/**
+ * Storage is temporarily not available
+ */
+class StorageNotAvailableException extends \Exception {
+}
diff --git a/public.php b/public.php
index 1f858fd073d..2ac082dba57 100644
--- a/public.php
+++ b/public.php
@@ -17,7 +17,7 @@ try {
if (!$pathInfo && !isset($_GET['service'])) {
header('HTTP/1.0 404 Not Found');
exit;
- } elseif ($_GET['service']) {
+ } elseif (isset($_GET['service'])) {
$service = $_GET['service'];
} else {
$pathInfo = trim($pathInfo, '/');