From f22af90c09926192ff17c77755c0359c7e0c072f Mon Sep 17 00:00:00 2001
From: Vincent Petry <pvince81@owncloud.com>
Date: Tue, 28 Jun 2016 12:09:58 +0200
Subject: Hide revert button when no permission to revert

---
 apps/files_versions/js/versionstabview.js          |  6 ++++
 apps/files_versions/lib/Storage.php                |  8 +++++
 apps/files_versions/tests/VersioningTest.php       | 38 +++++++++++++++++++++-
 .../files_versions/tests/js/versionstabviewSpec.js | 28 +++++++++++++++-
 4 files changed, 78 insertions(+), 2 deletions(-)

(limited to 'apps')

diff --git a/apps/files_versions/js/versionstabview.js b/apps/files_versions/js/versionstabview.js
index 0e17fff466a..b9ccf03c3e2 100644
--- a/apps/files_versions/js/versionstabview.js
+++ b/apps/files_versions/js/versionstabview.js
@@ -15,7 +15,9 @@
 		'<a href="{{downloadUrl}}" class="downloadVersion"><img src="{{downloadIconUrl}}" />' +
 		'<span class="versiondate has-tooltip" title="{{formattedTimestamp}}">{{relativeTimestamp}}</span>' +
 		'</a>' +
+		'{{#canRevert}}' +
 		'<a href="#" class="revertVersion" title="{{revertLabel}}"><img src="{{revertIconUrl}}" /></a>' +
+		'{{/canRevert}}' +
 		'</li>';
 
 	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 93f8b848ce8..6345d4c303b 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 2a65682f0fe..832f7bcc66f 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 306dd66be2a..94285c93aba 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');
 		});
-- 
cgit v1.2.3