diff --git a/apps/files_versions/js/versionstabview.js b/apps/files_versions/js/versionstabview.js
index 0e17fff466..b9ccf03c3e 100644
--- a/apps/files_versions/js/versionstabview.js
+++ b/apps/files_versions/js/versionstabview.js
@@ -15,7 +15,9 @@
'' +
'{{relativeTimestamp}}' +
'' +
+ '{{#canRevert}}' +
'' +
+ '{{/canRevert}}' +
'';
var TEMPLATE =
@@ -109,6 +111,9 @@
},
error: function() {
+ fileInfoModel.trigger('busy', fileInfoModel, false);
+ self.$el.find('.versions').removeClass('hidden');
+ self._toggleLoading(false);
OC.Notification.showTemporary(
t('files_version', 'Failed to revert {file} to revision {timestamp}.', {
file: versionModel.getFullPath(),
@@ -183,6 +188,7 @@
revertIconUrl: OC.imagePath('core', 'actions/history'),
previewUrl: version.getPreviewUrl(),
revertLabel: t('files_versions', 'Restore'),
+ canRevert: (this.collection.getFileInfo().get('permissions') & OC.PERMISSION_UPDATE) !== 0
}, version.attributes);
},
diff --git a/apps/files_versions/lib/Storage.php b/apps/files_versions/lib/Storage.php
index 93f8b848ce..6345d4c303 100644
--- a/apps/files_versions/lib/Storage.php
+++ b/apps/files_versions/lib/Storage.php
@@ -320,8 +320,16 @@ class Storage {
// add expected leading slash
$file = '/' . ltrim($file, '/');
list($uid, $filename) = self::getUidAndFilename($file);
+ if ($uid === null || trim($filename, '/') === '') {
+ return false;
+ }
$users_view = new View('/'.$uid);
$files_view = new View('/'. User::getUser().'/files');
+
+ if (!$files_view->isUpdatable($filename)) {
+ return false;
+ }
+
$versionCreated = false;
//first create a new version
diff --git a/apps/files_versions/tests/VersioningTest.php b/apps/files_versions/tests/VersioningTest.php
index 2a65682f0f..832f7bcc66 100644
--- a/apps/files_versions/tests/VersioningTest.php
+++ b/apps/files_versions/tests/VersioningTest.php
@@ -625,6 +625,40 @@ class VersioningTest extends \Test\TestCase {
$this->doTestRestore();
}
+ public function testRestoreNoPermission() {
+ $this->loginAsUser(self::TEST_VERSIONS_USER);
+
+ $userHome = \OC::$server->getUserFolder(self::TEST_VERSIONS_USER);
+ $node = $userHome->newFolder('folder');
+ $file = $node->newFile('test.txt');
+
+ $share = \OC::$server->getShareManager()->newShare();
+ $share->setNode($node)
+ ->setShareType(\OCP\Share::SHARE_TYPE_USER)
+ ->setSharedBy(self::TEST_VERSIONS_USER)
+ ->setSharedWith(self::TEST_VERSIONS_USER2)
+ ->setPermissions(\OCP\Constants::PERMISSION_READ);
+ $share = \OC::$server->getShareManager()->createShare($share);
+
+ $versions = $this->createAndCheckVersions(
+ \OC\Files\Filesystem::getView(),
+ 'folder/test.txt'
+ );
+
+ $file->putContent('test file');
+
+ $this->loginAsUser(self::TEST_VERSIONS_USER2);
+
+ $firstVersion = current($versions);
+
+ $this->assertFalse(\OCA\Files_Versions\Storage::rollback('folder/test.txt', $firstVersion['version']), 'Revert did not happen');
+
+ $this->loginAsUser(self::TEST_VERSIONS_USER);
+
+ \OC::$server->getShareManager()->deleteShare($share);
+ $this->assertEquals('test file', $file->getContent(), 'File content has not changed');
+ }
+
/**
* @param string $hookName name of hook called
* @param string $params variable to receive parameters provided by hook
@@ -685,7 +719,7 @@ class VersioningTest extends \Test\TestCase {
$params = array();
$this->connectMockHooks('rollback', $params);
- \OCA\Files_Versions\Storage::rollback('sub/test.txt', $t2);
+ $this->assertTrue(\OCA\Files_Versions\Storage::rollback('sub/test.txt', $t2));
$expectedParams = array(
'path' => '/sub/test.txt',
);
@@ -829,6 +863,8 @@ class VersioningTest extends \Test\TestCase {
// note: we cannot predict how many versions are created due to
// test run timing
$this->assertGreaterThan(0, count($versions));
+
+ return $versions;
}
/**
diff --git a/apps/files_versions/tests/js/versionstabviewSpec.js b/apps/files_versions/tests/js/versionstabviewSpec.js
index 306dd66be2..94285c93ab 100644
--- a/apps/files_versions/tests/js/versionstabviewSpec.js
+++ b/apps/files_versions/tests/js/versionstabviewSpec.js
@@ -39,7 +39,8 @@ describe('OCA.Versions.VersionsTabView', function() {
fetchStub = sinon.stub(VersionCollection.prototype, 'fetch');
fileInfoModel = new OCA.Files.FileInfoModel({
id: 123,
- name: 'test.txt'
+ name: 'test.txt',
+ permissions: OC.PERMISSION_READ | OC.PERMISSION_UPDATE
});
tabView = new VersionsTabView();
tabView.render();
@@ -86,12 +87,37 @@ describe('OCA.Versions.VersionsTabView', function() {
expect($item.find('.revertVersion').length).toEqual(1);
expect($item.find('.preview').attr('src')).toEqual(version2.getPreviewUrl());
});
+
+ it('does not render revert button when no update permissions', function() {
+
+ fileInfoModel.set('permissions', OC.PERMISSION_READ);
+ tabView.setFileInfo(fileInfoModel);
+ tabView.collection.set(testVersions);
+
+ var version1 = testVersions[0];
+ var version2 = testVersions[1];
+ var $versions = tabView.$el.find('.versions>li');
+ expect($versions.length).toEqual(2);
+ var $item = $versions.eq(0);
+ expect($item.find('.downloadVersion').attr('href')).toEqual(version1.getDownloadUrl());
+ expect($item.find('.versiondate').text()).toEqual('seconds ago');
+ expect($item.find('.revertVersion').length).toEqual(0);
+ expect($item.find('.preview').attr('src')).toEqual(version1.getPreviewUrl());
+
+ $item = $versions.eq(1);
+ expect($item.find('.downloadVersion').attr('href')).toEqual(version2.getDownloadUrl());
+ expect($item.find('.versiondate').text()).toEqual('2 days ago');
+ expect($item.find('.revertVersion').length).toEqual(0);
+ expect($item.find('.preview').attr('src')).toEqual(version2.getPreviewUrl());
+ });
});
describe('More versions', function() {
var hasMoreResultsStub;
beforeEach(function() {
+ tabView.setFileInfo(fileInfoModel);
+ fetchStub.reset();
tabView.collection.set(testVersions);
hasMoreResultsStub = sinon.stub(VersionCollection.prototype, 'hasMoreResults');
});