@@ -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); | |||
}, | |||
@@ -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 |
@@ -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; | |||
} | |||
/** |
@@ -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'); | |||
}); |