summaryrefslogtreecommitdiffstats
path: root/apps
diff options
context:
space:
mode:
Diffstat (limited to 'apps')
-rw-r--r--apps/files/css/files.css14
-rw-r--r--apps/files/js/filelist.js28
-rw-r--r--apps/files/tests/js/filelistSpec.js51
-rw-r--r--apps/files_encryption/hooks/hooks.php54
-rwxr-xr-xapps/files_encryption/lib/helper.php4
-rw-r--r--apps/files_encryption/settings-admin.php3
-rw-r--r--apps/files_encryption/templates/settings-admin.php4
-rw-r--r--apps/files_encryption/templates/settings-personal.php9
-rw-r--r--apps/files_encryption/tests/hooks.php52
-rw-r--r--apps/files_sharing/ajax/publicpreview.php4
-rw-r--r--apps/files_sharing/appinfo/update.php6
-rw-r--r--apps/files_sharing/js/sharedfilelist.js4
-rw-r--r--apps/files_sharing/lib/api.php29
-rw-r--r--apps/files_sharing/lib/external/storage.php9
-rw-r--r--apps/files_sharing/templates/public.php2
-rw-r--r--apps/files_sharing/tests/api.php74
-rw-r--r--apps/files_sharing/tests/update.php1
-rw-r--r--apps/files_versions/appinfo/app.php7
-rw-r--r--apps/files_versions/lib/hooks.php30
-rw-r--r--apps/files_versions/lib/versions.php70
-rw-r--r--apps/files_versions/tests/versions.php108
21 files changed, 470 insertions, 93 deletions
diff --git a/apps/files/css/files.css b/apps/files/css/files.css
index 287dedc23f2..4a8bd5bb30f 100644
--- a/apps/files/css/files.css
+++ b/apps/files/css/files.css
@@ -152,16 +152,20 @@ table th .columntitle.name {
padding-right: 80px;
margin-left: 50px;
}
-/* hover effect on sortable column */
-table th a.columntitle:hover {
- color: #000;
-}
+
+.sort-indicator.hidden { visibility: hidden; }
table th .sort-indicator {
width: 10px;
height: 8px;
margin-left: 10px;
display: inline-block;
}
+table th:hover .sort-indicator.hidden {
+ width: 10px;
+ height: 8px;
+ margin-left: 10px;
+ visibility: visible;
+}
table th, table td { border-bottom:1px solid #ddd; text-align:left; font-weight:normal; }
table td {
padding: 0 15px;
@@ -367,7 +371,6 @@ table td.filename .uploadtext {
left: 18px;
}
-
#fileList tr td.filename {
position: relative;
width: 100%;
@@ -432,7 +435,6 @@ a.action>img {
margin-bottom: -1px;
}
-
#fileList a.action {
display: inline;
padding: 18px 8px;
diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js
index 61e73b7bebc..4fa8ca65e39 100644
--- a/apps/files/js/filelist.js
+++ b/apps/files/js/filelist.js
@@ -18,8 +18,8 @@
this.initialize($el, options);
};
FileList.prototype = {
- SORT_INDICATOR_ASC_CLASS: 'icon-triangle-s',
- SORT_INDICATOR_DESC_CLASS: 'icon-triangle-n',
+ SORT_INDICATOR_ASC_CLASS: 'icon-triangle-n',
+ SORT_INDICATOR_DESC_CLASS: 'icon-triangle-s',
id: 'files',
appName: t('files', 'Files'),
@@ -371,7 +371,12 @@
this.setSort(sort, (this._sortDirection === 'desc')?'asc':'desc');
}
else {
- this.setSort(sort, 'asc');
+ if ( sort === 'name' ) { //default sorting of name is opposite to size and mtime
+ this.setSort(sort, 'asc');
+ }
+ else {
+ this.setSort(sort, 'desc');
+ }
}
this.reload();
}
@@ -707,6 +712,7 @@
* @param options map of attributes:
* - "updateSummary": true to update the summary after adding (default), false otherwise
* - "silent": true to prevent firing events like "fileActionsReady"
+ * - "animate": true to animate preview loading (defaults to true here)
* @return new tr element (not appended to the table)
*/
add: function(fileData, options) {
@@ -714,7 +720,7 @@
var $tr;
var $rows;
var $insertionPoint;
- options = options || {};
+ options = _.extend({animate: true}, options || {});
// there are three situations to cover:
// 1) insertion point is visible on the current page
@@ -772,6 +778,7 @@
* @param options map of attributes:
* - "index" optional index at which to insert the element
* - "updateSummary" true to update the summary after adding (default), false otherwise
+ * - "animate" true to animate the preview rendering
* @return new tr element (not appended to the table)
*/
_renderRow: function(fileData, options) {
@@ -813,7 +820,7 @@
if (fileData.isPreviewAvailable) {
// lazy load / newly inserted td ?
- if (!fileData.icon) {
+ if (options.animate) {
this.lazyLoadPreview({
path: path + '/' + fileData.name,
mime: mime,
@@ -914,16 +921,25 @@
this._sort = sort;
this._sortDirection = (direction === 'desc')?'desc':'asc';
this._sortComparator = comparator;
+
if (direction === 'desc') {
this._sortComparator = function(fileInfo1, fileInfo2) {
return -comparator(fileInfo1, fileInfo2);
};
}
this.$el.find('thead th .sort-indicator')
- .removeClass(this.SORT_INDICATOR_ASC_CLASS + ' ' + this.SORT_INDICATOR_DESC_CLASS);
+ .removeClass(this.SORT_INDICATOR_ASC_CLASS)
+ .removeClass(this.SORT_INDICATOR_DESC_CLASS)
+ .toggleClass('hidden', true)
+ .addClass(this.SORT_INDICATOR_DESC_CLASS);
+
this.$el.find('thead th.column-' + sort + ' .sort-indicator')
+ .removeClass(this.SORT_INDICATOR_ASC_CLASS)
+ .removeClass(this.SORT_INDICATOR_DESC_CLASS)
+ .toggleClass('hidden', false)
.addClass(direction === 'desc' ? this.SORT_INDICATOR_DESC_CLASS : this.SORT_INDICATOR_ASC_CLASS);
},
+
/**
* Reloads the file list using ajax call
*
diff --git a/apps/files/tests/js/filelistSpec.js b/apps/files/tests/js/filelistSpec.js
index ae22ae0123e..0580177c5ff 100644
--- a/apps/files/tests/js/filelistSpec.js
+++ b/apps/files/tests/js/filelistSpec.js
@@ -1696,7 +1696,7 @@ describe('OCA.Files.FileList tests', function() {
var url = fakeServer.requests[0].url;
var query = OC.parseQueryString(url.substr(url.indexOf('?') + 1));
expect(query.sort).toEqual('size');
- expect(query.sortdirection).toEqual('asc');
+ expect(query.sortdirection).toEqual('desc');
});
it('Toggles sort direction when clicking on already sorted column', function() {
fileList.$el.find('.column-name .columntitle').click();
@@ -1710,37 +1710,51 @@ describe('OCA.Files.FileList tests', function() {
var ASC_CLASS = fileList.SORT_INDICATOR_ASC_CLASS;
var DESC_CLASS = fileList.SORT_INDICATOR_DESC_CLASS;
fileList.$el.find('.column-size .columntitle').click();
- // moves triangle to size column
+ // moves triangle to size column, check indicator on name is hidden
expect(
- fileList.$el.find('.column-name .sort-indicator').hasClass(ASC_CLASS + ' ' + DESC_CLASS)
+ fileList.$el.find('.column-name .sort-indicator').hasClass('hidden')
+ ).toEqual(true);
+ // check indicator on size is visible and defaults to descending
+ expect(
+ fileList.$el.find('.column-size .sort-indicator').hasClass('hidden')
).toEqual(false);
expect(
- fileList.$el.find('.column-size .sort-indicator').hasClass(ASC_CLASS)
+ fileList.$el.find('.column-size .sort-indicator').hasClass(DESC_CLASS)
).toEqual(true);
// click again on size column, reverses direction
fileList.$el.find('.column-size .columntitle').click();
expect(
- fileList.$el.find('.column-size .sort-indicator').hasClass(DESC_CLASS)
+ fileList.$el.find('.column-size .sort-indicator').hasClass('hidden')
+ ).toEqual(false);
+ expect(
+ fileList.$el.find('.column-size .sort-indicator').hasClass(ASC_CLASS)
).toEqual(true);
// click again on size column, reverses direction
fileList.$el.find('.column-size .columntitle').click();
expect(
- fileList.$el.find('.column-size .sort-indicator').hasClass(ASC_CLASS)
+ fileList.$el.find('.column-size .sort-indicator').hasClass('hidden')
+ ).toEqual(false);
+ expect(
+ fileList.$el.find('.column-size .sort-indicator').hasClass(DESC_CLASS)
).toEqual(true);
// click on mtime column, moves indicator there
fileList.$el.find('.column-mtime .columntitle').click();
expect(
- fileList.$el.find('.column-size .sort-indicator').hasClass(ASC_CLASS + ' ' + DESC_CLASS)
+ fileList.$el.find('.column-size .sort-indicator').hasClass('hidden')
+ ).toEqual(true);
+ expect(
+ fileList.$el.find('.column-mtime .sort-indicator').hasClass('hidden')
).toEqual(false);
expect(
- fileList.$el.find('.column-mtime .sort-indicator').hasClass(ASC_CLASS)
+ fileList.$el.find('.column-mtime .sort-indicator').hasClass(DESC_CLASS)
).toEqual(true);
});
it('Uses correct sort comparator when inserting files', function() {
testFiles.sort(OCA.Files.FileList.Comparators.size);
+ testFiles.reverse(); //default is descending
// this will make it reload the testFiles with the correct sorting
fileList.$el.find('.column-size .columntitle').click();
expect(fakeServer.requests.length).toEqual(1);
@@ -1764,17 +1778,16 @@ describe('OCA.Files.FileList tests', function() {
etag: '999'
};
fileList.add(newFileData);
+ expect(fileList.findFileEl('Three.pdf').index()).toEqual(0);
+ expect(fileList.findFileEl('new file.txt').index()).toEqual(1);
+ expect(fileList.findFileEl('Two.jpg').index()).toEqual(2);
+ expect(fileList.findFileEl('somedir').index()).toEqual(3);
+ expect(fileList.findFileEl('One.txt').index()).toEqual(4);
expect(fileList.files.length).toEqual(5);
expect(fileList.$fileList.find('tr').length).toEqual(5);
- expect(fileList.findFileEl('One.txt').index()).toEqual(0);
- expect(fileList.findFileEl('somedir').index()).toEqual(1);
- expect(fileList.findFileEl('Two.jpg').index()).toEqual(2);
- expect(fileList.findFileEl('new file.txt').index()).toEqual(3);
- expect(fileList.findFileEl('Three.pdf').index()).toEqual(4);
});
it('Uses correct reversed sort comparator when inserting files', function() {
testFiles.sort(OCA.Files.FileList.Comparators.size);
- testFiles.reverse();
// this will make it reload the testFiles with the correct sorting
fileList.$el.find('.column-size .columntitle').click();
expect(fakeServer.requests.length).toEqual(1);
@@ -1811,13 +1824,13 @@ describe('OCA.Files.FileList tests', function() {
etag: '999'
};
fileList.add(newFileData);
+ expect(fileList.findFileEl('One.txt').index()).toEqual(0);
+ expect(fileList.findFileEl('somedir').index()).toEqual(1);
+ expect(fileList.findFileEl('Two.jpg').index()).toEqual(2);
+ expect(fileList.findFileEl('new file.txt').index()).toEqual(3);
+ expect(fileList.findFileEl('Three.pdf').index()).toEqual(4);
expect(fileList.files.length).toEqual(5);
expect(fileList.$fileList.find('tr').length).toEqual(5);
- expect(fileList.findFileEl('One.txt').index()).toEqual(4);
- expect(fileList.findFileEl('somedir').index()).toEqual(3);
- expect(fileList.findFileEl('Two.jpg').index()).toEqual(2);
- expect(fileList.findFileEl('new file.txt').index()).toEqual(1);
- expect(fileList.findFileEl('Three.pdf').index()).toEqual(0);
});
});
/**
diff --git a/apps/files_encryption/hooks/hooks.php b/apps/files_encryption/hooks/hooks.php
index c40fc43f7d5..4a257f2ad33 100644
--- a/apps/files_encryption/hooks/hooks.php
+++ b/apps/files_encryption/hooks/hooks.php
@@ -419,21 +419,51 @@ class Hooks {
$mp1 = $view->getMountPoint('/' . $user . '/files/' . $params['oldpath']);
$mp2 = $view->getMountPoint('/' . $user . '/files/' . $params['newpath']);
+ $type = $view->is_dir('/' . $user . '/files/' . $params['oldpath']) ? 'folder' : 'file';
+
if ($mp1 === $mp2) {
self::$renamedFiles[$params['oldpath']] = array(
'uid' => $ownerOld,
- 'path' => $pathOld);
+ 'path' => $pathOld,
+ 'type' => $type,
+ 'operation' => 'rename',
+ );
+
}
}
/**
- * after a file is renamed, rename its keyfile and share-keys also fix the file size and fix also the sharing
- * @param array $params array with oldpath and newpath
+ * mark file as renamed so that we know the original source after the file was renamed
+ * @param array $params with the old path and the new path
+ */
+ public static function preCopy($params) {
+ $user = \OCP\User::getUser();
+ $view = new \OC\Files\View('/');
+ $util = new Util($view, $user);
+ list($ownerOld, $pathOld) = $util->getUidAndFilename($params['oldpath']);
+
+ // we only need to rename the keys if the rename happens on the same mountpoint
+ // otherwise we perform a stream copy, so we get a new set of keys
+ $mp1 = $view->getMountPoint('/' . $user . '/files/' . $params['oldpath']);
+ $mp2 = $view->getMountPoint('/' . $user . '/files/' . $params['newpath']);
+
+ $type = $view->is_dir('/' . $user . '/files/' . $params['oldpath']) ? 'folder' : 'file';
+
+ if ($mp1 === $mp2) {
+ self::$renamedFiles[$params['oldpath']] = array(
+ 'uid' => $ownerOld,
+ 'path' => $pathOld,
+ 'type' => $type,
+ 'operation' => 'copy');
+ }
+ }
+
+ /**
+ * after a file is renamed/copied, rename/copy its keyfile and share-keys also fix the file size and fix also the sharing
*
- * This function is connected to the rename signal of OC_Filesystem and adjust the name and location
- * of the stored versions along the actual file
+ * @param array $params array with oldpath and newpath
*/
- public static function postRename($params) {
+ public static function postRenameOrCopy($params) {
if (\OCP\App::isEnabled('files_encryption') === false) {
return true;
@@ -451,6 +481,8 @@ class Hooks {
isset(self::$renamedFiles[$params['oldpath']]['path'])) {
$ownerOld = self::$renamedFiles[$params['oldpath']]['uid'];
$pathOld = self::$renamedFiles[$params['oldpath']]['path'];
+ $type = self::$renamedFiles[$params['oldpath']]['type'];
+ $operation = self::$renamedFiles[$params['oldpath']]['operation'];
unset(self::$renamedFiles[$params['oldpath']]);
} else {
\OCP\Util::writeLog('Encryption library', "can't get path and owner from the file before it was renamed", \OCP\Util::DEBUG);
@@ -485,8 +517,7 @@ class Hooks {
}
// handle share keys
- if (!$view->is_dir($oldKeyfilePath)) {
- $type = 'file';
+ if ($type === 'file') {
$oldKeyfilePath .= '.key';
$newKeyfilePath .= '.key';
@@ -494,18 +525,17 @@ class Hooks {
$matches = Helper::findShareKeys($oldShareKeyPath, $view);
foreach ($matches as $src) {
$dst = \OC\Files\Filesystem::normalizePath(str_replace($pathOld, $pathNew, $src));
- $view->rename($src, $dst);
+ $view->$operation($src, $dst);
}
} else {
- $type = "folder";
// handle share-keys folders
- $view->rename($oldShareKeyPath, $newShareKeyPath);
+ $view->$operation($oldShareKeyPath, $newShareKeyPath);
}
// Rename keyfile so it isn't orphaned
if ($view->file_exists($oldKeyfilePath)) {
- $view->rename($oldKeyfilePath, $newKeyfilePath);
+ $view->$operation($oldKeyfilePath, $newKeyfilePath);
}
diff --git a/apps/files_encryption/lib/helper.php b/apps/files_encryption/lib/helper.php
index fed0788028f..ed42cec326a 100755
--- a/apps/files_encryption/lib/helper.php
+++ b/apps/files_encryption/lib/helper.php
@@ -62,7 +62,9 @@ class Helper {
public static function registerFilesystemHooks() {
\OCP\Util::connectHook('OC_Filesystem', 'rename', 'OCA\Encryption\Hooks', 'preRename');
- \OCP\Util::connectHook('OC_Filesystem', 'post_rename', 'OCA\Encryption\Hooks', 'postRename');
+ \OCP\Util::connectHook('OC_Filesystem', 'post_rename', 'OCA\Encryption\Hooks', 'postRenameOrCopy');
+ \OCP\Util::connectHook('OC_Filesystem', 'copy', 'OCA\Encryption\Hooks', 'preCopy');
+ \OCP\Util::connectHook('OC_Filesystem', 'post_copy', 'OCA\Encryption\Hooks', 'postRenameOrCopy');
\OCP\Util::connectHook('OC_Filesystem', 'post_delete', 'OCA\Encryption\Hooks', 'postDelete');
\OCP\Util::connectHook('OC_Filesystem', 'delete', 'OCA\Encryption\Hooks', 'preDelete');
\OCP\Util::connectHook('OC_Filesystem', 'post_umount', 'OCA\Encryption\Hooks', 'postUmount');
diff --git a/apps/files_encryption/settings-admin.php b/apps/files_encryption/settings-admin.php
index 88e06613997..496a7cffb50 100644
--- a/apps/files_encryption/settings-admin.php
+++ b/apps/files_encryption/settings-admin.php
@@ -12,8 +12,11 @@ $tmpl = new OCP\Template('files_encryption', 'settings-admin');
// Check if an adminRecovery account is enabled for recovering files after lost pwd
$recoveryAdminEnabled = \OC::$server->getAppConfig()->getValue('files_encryption', 'recoveryAdminEnabled', '0');
+$session = new \OCA\Encryption\Session(new \OC\Files\View('/'));
+$initStatus = $session->getInitialized();
$tmpl->assign('recoveryEnabled', $recoveryAdminEnabled);
+$tmpl->assign('initStatus', $initStatus);
\OCP\Util::addscript('files_encryption', 'settings-admin');
\OCP\Util::addscript('core', 'multiselect');
diff --git a/apps/files_encryption/templates/settings-admin.php b/apps/files_encryption/templates/settings-admin.php
index d4e6abf004a..a97261dc1c9 100644
--- a/apps/files_encryption/templates/settings-admin.php
+++ b/apps/files_encryption/templates/settings-admin.php
@@ -1,6 +1,9 @@
<form id="encryption" class="section">
<h2><?php p($l->t('Encryption')); ?></h2>
+ <?php if($_["initStatus"] === \OCA\Encryption\Session::NOT_INITIALIZED): ?>
+ <?php p($l->t("Encryption App is enabled but your keys are not initialized, please log-out and log-in again")); ?>
+ <?php else: ?>
<p>
<?php p($l->t("Enable recovery key (allow to recover users files in case of password loss):")); ?>
<br/>
@@ -57,4 +60,5 @@
</button>
<span class="msg"></span>
</p>
+ <?php endif; ?>
</form>
diff --git a/apps/files_encryption/templates/settings-personal.php b/apps/files_encryption/templates/settings-personal.php
index e9988df3275..3d44b9fa9a5 100644
--- a/apps/files_encryption/templates/settings-personal.php
+++ b/apps/files_encryption/templates/settings-personal.php
@@ -1,7 +1,11 @@
<form id="encryption" class="section">
<h2><?php p( $l->t( 'Encryption' ) ); ?></h2>
- <?php if ( $_["initialized"] === '1' ): ?>
+ <?php if ( $_["initialized"] === \OCA\Encryption\Session::NOT_INITIALIZED ): ?>
+
+ <?php p($l->t("Encryption App is enabled but your keys are not initialized, please log-out and log-in again")); ?>
+
+ <?php elseif ( $_["initialized"] === \OCA\Encryption\Session::INIT_EXECUTED ): ?>
<p>
<a name="changePKPasswd" />
<label for="changePrivateKeyPasswd">
@@ -33,9 +37,8 @@
</button>
<span class="msg"></span>
</p>
- <?php endif; ?>
- <?php if ( $_["recoveryEnabled"] && $_["privateKeySet"] ): ?>
+ <?php elseif ( $_["recoveryEnabled"] && $_["privateKeySet"] && $_["initialized"] === \OCA\Encryption\Session::INIT_SUCCESSFUL ): ?>
<br />
<p>
<label for="userEnableRecovery"><?php p( $l->t( "Enable password recovery:" ) ); ?></label>
diff --git a/apps/files_encryption/tests/hooks.php b/apps/files_encryption/tests/hooks.php
index 5eda8df01b9..cc5b6d5b6f6 100644
--- a/apps/files_encryption/tests/hooks.php
+++ b/apps/files_encryption/tests/hooks.php
@@ -336,6 +336,58 @@ class Test_Encryption_Hooks extends \PHPUnit_Framework_TestCase {
}
/**
+ * test rename operation
+ */
+ function testCopyHook() {
+
+ // save file with content
+ $cryptedFile = file_put_contents('crypt:///' . self::TEST_ENCRYPTION_HOOKS_USER1 . '/files/' . $this->filename, $this->data);
+
+ // test that data was successfully written
+ $this->assertTrue(is_int($cryptedFile));
+
+ // check if keys exists
+ $this->assertTrue($this->rootView->file_exists(
+ '/' . self::TEST_ENCRYPTION_HOOKS_USER1 . '/files_encryption/share-keys/'
+ . $this->filename . '.' . self::TEST_ENCRYPTION_HOOKS_USER1 . '.shareKey'));
+
+ $this->assertTrue($this->rootView->file_exists(
+ '/' . self::TEST_ENCRYPTION_HOOKS_USER1 . '/files_encryption/keyfiles/'
+ . $this->filename . '.key'));
+
+ // make subfolder and sub-subfolder
+ $this->rootView->mkdir('/' . self::TEST_ENCRYPTION_HOOKS_USER1 . '/files/' . $this->folder);
+ $this->rootView->mkdir('/' . self::TEST_ENCRYPTION_HOOKS_USER1 . '/files/' . $this->folder . '/' . $this->folder);
+
+ $this->assertTrue($this->rootView->is_dir('/' . self::TEST_ENCRYPTION_HOOKS_USER1 . '/files/' . $this->folder . '/' . $this->folder));
+
+ // copy the file to the sub-subfolder
+ \OC\Files\Filesystem::copy($this->filename, '/' . $this->folder . '/' . $this->folder . '/' . $this->filename);
+
+ $this->assertTrue($this->rootView->file_exists('/' . self::TEST_ENCRYPTION_HOOKS_USER1 . '/files/' . $this->filename));
+ $this->assertTrue($this->rootView->file_exists('/' . self::TEST_ENCRYPTION_HOOKS_USER1 . '/files/' . $this->folder . '/' . $this->folder . '/' . $this->filename));
+
+ // keys should be copied too
+ $this->assertTrue($this->rootView->file_exists(
+ '/' . self::TEST_ENCRYPTION_HOOKS_USER1 . '/files_encryption/share-keys/'
+ . $this->filename . '.' . self::TEST_ENCRYPTION_HOOKS_USER1 . '.shareKey'));
+ $this->assertTrue($this->rootView->file_exists(
+ '/' . self::TEST_ENCRYPTION_HOOKS_USER1 . '/files_encryption/keyfiles/'
+ . $this->filename . '.key'));
+
+ $this->assertTrue($this->rootView->file_exists(
+ '/' . self::TEST_ENCRYPTION_HOOKS_USER1 . '/files_encryption/share-keys/' . $this->folder . '/' . $this->folder . '/'
+ . $this->filename . '.' . self::TEST_ENCRYPTION_HOOKS_USER1 . '.shareKey'));
+ $this->assertTrue($this->rootView->file_exists(
+ '/' . self::TEST_ENCRYPTION_HOOKS_USER1 . '/files_encryption/keyfiles/' . $this->folder . '/' . $this->folder . '/'
+ . $this->filename . '.key'));
+
+ // cleanup
+ $this->rootView->unlink('/' . self::TEST_ENCRYPTION_HOOKS_USER1 . '/files/' . $this->folder);
+ $this->rootView->unlink('/' . self::TEST_ENCRYPTION_HOOKS_USER1 . '/files/' . $this->filename);
+ }
+
+ /**
* @brief replacing encryption keys during password change should be allowed
* until the user logged in for the first time
*/
diff --git a/apps/files_sharing/ajax/publicpreview.php b/apps/files_sharing/ajax/publicpreview.php
index 0b2af7a6e59..f5343a7ef26 100644
--- a/apps/files_sharing/ajax/publicpreview.php
+++ b/apps/files_sharing/ajax/publicpreview.php
@@ -70,10 +70,6 @@ if(substr($path, 0, 1) === '/') {
$path = substr($path, 1);
}
-if ($keepAspect === true) {
- $maxY = $maxX;
-}
-
if($maxX === 0 || $maxY === 0) {
\OC_Response::setStatus(\OC_Response::STATUS_BAD_REQUEST);
\OC_Log::write('core-preview', 'x and/or y set to 0', \OC_Log::DEBUG);
diff --git a/apps/files_sharing/appinfo/update.php b/apps/files_sharing/appinfo/update.php
index fc547ba349d..72acdbac736 100644
--- a/apps/files_sharing/appinfo/update.php
+++ b/apps/files_sharing/appinfo/update.php
@@ -32,6 +32,7 @@ function updateFilePermissions($chunkSize = 99) {
}
}
+ $connection = \OC_DB::getConnection();
$chunkedPermissionList = array_chunk($updatedRows, $chunkSize, true);
foreach ($chunkedPermissionList as $subList) {
@@ -39,7 +40,7 @@ function updateFilePermissions($chunkSize = 99) {
//update share table
$ids = implode(',', array_keys($subList));
foreach ($subList as $id => $permission) {
- $statement .= "WHEN " . $id . " THEN " . $permission . " ";
+ $statement .= "WHEN " . $connection->quote($id, \PDO::PARAM_INT) . " THEN " . $permission . " ";
}
$statement .= ' END WHERE `id` IN (' . $ids . ')';
@@ -95,6 +96,7 @@ function removeSharedFolder($mkdirs = true, $chunkSize = 99) {
}
$chunkedShareList = array_chunk($shares, $chunkSize, true);
+ $connection = \OC_DB::getConnection();
foreach ($chunkedShareList as $subList) {
@@ -102,7 +104,7 @@ function removeSharedFolder($mkdirs = true, $chunkSize = 99) {
//update share table
$ids = implode(',', array_keys($subList));
foreach ($subList as $id => $target) {
- $statement .= "WHEN " . $id . " THEN '/Shared" . $target . "' ";
+ $statement .= "WHEN " . $connection->quote($id, \PDO::PARAM_INT) . " THEN " . $connection->quote('/Shared' . $target, \PDO::PARAM_STR);
}
$statement .= ' END WHERE `id` IN (' . $ids . ')';
diff --git a/apps/files_sharing/js/sharedfilelist.js b/apps/files_sharing/js/sharedfilelist.js
index d5c65a6c681..7a43185a2d7 100644
--- a/apps/files_sharing/js/sharedfilelist.js
+++ b/apps/files_sharing/js/sharedfilelist.js
@@ -59,6 +59,9 @@
$tr.attr('data-share-id', _.pluck(fileData.shares, 'id').join(','));
if (this._sharedWithUser) {
$tr.attr('data-share-owner', fileData.shareOwner);
+ $tr.attr('data-mounttype', 'shared-root');
+ var permission = parseInt($tr.attr('data-permissions')) | OC.PERMISSION_DELETE;
+ $tr.attr('data-permissions', permission);
}
return $tr;
},
@@ -162,7 +165,6 @@
else {
file.type = 'file';
if (share.isPreviewAvailable) {
- file.icon = true;
file.isPreviewAvailable = true;
}
}
diff --git a/apps/files_sharing/lib/api.php b/apps/files_sharing/lib/api.php
index 50ba74f5beb..faf141db25f 100644
--- a/apps/files_sharing/lib/api.php
+++ b/apps/files_sharing/lib/api.php
@@ -339,6 +339,8 @@ class Api {
return self::updatePassword($share, $params);
} elseif (isset($params['_put']['publicUpload'])) {
return self::updatePublicUpload($share, $params);
+ } elseif (isset($params['_put']['expireDate'])) {
+ return self::updateExpireDate($share, $params);
}
} catch (\Exception $e) {
@@ -409,7 +411,7 @@ class Api {
if ($share['item_type'] !== 'folder' ||
(int)$share['share_type'] !== \OCP\Share::SHARE_TYPE_LINK ) {
- return new \OC_OCS_Result(null, 404, "public upload is only possible for public shared folders");
+ return new \OC_OCS_Result(null, 400, "public upload is only possible for public shared folders");
}
// read, create, update (7) if public upload is enabled or
@@ -421,6 +423,29 @@ class Api {
}
/**
+ * set expire date for public link share
+ * @param array $share information about the share
+ * @param array $params contains 'expireDate' which needs to be a well formated date string, e.g DD-MM-YYYY
+ * @return \OC_OCS_Result
+ */
+ private static function updateExpireDate($share, $params) {
+ // only public links can have a expire date
+ if ((int)$share['share_type'] !== \OCP\Share::SHARE_TYPE_LINK ) {
+ return new \OC_OCS_Result(null, 400, "expire date only exists for public link shares");
+ }
+
+ try {
+ $expireDateSet = \OCP\Share::setExpirationDate($share['item_type'], $share['item_source'], $params['_put']['expireDate'], (int)$share['stime']);
+ $result = ($expireDateSet) ? new \OC_OCS_Result() : new \OC_OCS_Result(null, 404, "couldn't set expire date");
+ } catch (\Exception $e) {
+ $result = new \OC_OCS_Result(null, 404, $e->getMessage());
+ }
+
+ return $result;
+
+ }
+
+ /**
* update password for public link share
* @param array $share information about the share
* @param array $params 'password'
@@ -555,7 +580,7 @@ class Api {
* @return array with: item_source, share_type, share_with, item_type, permissions
*/
private static function getShareFromId($shareID) {
- $sql = 'SELECT `file_source`, `item_source`, `share_type`, `share_with`, `item_type`, `permissions` FROM `*PREFIX*share` WHERE `id` = ?';
+ $sql = 'SELECT `file_source`, `item_source`, `share_type`, `share_with`, `item_type`, `permissions`, `stime` FROM `*PREFIX*share` WHERE `id` = ?';
$args = array($shareID);
$query = \OCP\DB::prepare($sql);
$result = $query->execute($args);
diff --git a/apps/files_sharing/lib/external/storage.php b/apps/files_sharing/lib/external/storage.php
index 3a0de51192e..855be2872b5 100644
--- a/apps/files_sharing/lib/external/storage.php
+++ b/apps/files_sharing/lib/external/storage.php
@@ -49,7 +49,12 @@ class Storage extends DAV implements ISharedStorage {
$this->remote = $options['remote'];
$this->remoteUser = $options['owner'];
list($protocol, $remote) = explode('://', $this->remote);
- list($host, $root) = explode('/', $remote, 2);
+ if (strpos($remote, '/')) {
+ list($host, $root) = explode('/', $remote, 2);
+ } else {
+ $host = $remote;
+ $root = '';
+ }
$secure = $protocol === 'https';
$root = rtrim($root, '/') . '/public.php/webdav';
$this->mountPoint = $options['mountpoint'];
@@ -148,7 +153,7 @@ class Storage extends DAV implements ISharedStorage {
// ownCloud instance is gone, likely to be a temporary server configuration error
throw $e;
}
- } catch(\Exception $shareException) {
+ } catch (\Exception $shareException) {
// todo, maybe handle 403 better and ask the user for a new password
throw $e;
}
diff --git a/apps/files_sharing/templates/public.php b/apps/files_sharing/templates/public.php
index 386fa7e17cd..8406b79cf1a 100644
--- a/apps/files_sharing/templates/public.php
+++ b/apps/files_sharing/templates/public.php
@@ -42,7 +42,7 @@
</div>
<?php elseif (substr($_['mimetype'], 0, strpos($_['mimetype'], '/')) == 'video'): ?>
<div id="imgframe">
- <video tabindex="0" controls="" autoplay="">
+ <video tabindex="0" controls="" preload="none">
<source src="<?php p($_['downloadURL']); ?>" type="<?php p($_['mimetype']); ?>" />
</video>
</div>
diff --git a/apps/files_sharing/tests/api.php b/apps/files_sharing/tests/api.php
index 72dd5816ea0..49571d4c3c2 100644
--- a/apps/files_sharing/tests/api.php
+++ b/apps/files_sharing/tests/api.php
@@ -940,6 +940,78 @@ class Test_Files_Sharing_Api extends Test_Files_Sharing_Base {
/**
* @medium
+ */
+ function testUpdateShareExpireDate() {
+
+ $fileInfo = $this->view->getFileInfo($this->folder);
+
+ // enforce expire date, by default 7 days after the file was shared
+ \OCP\Config::setAppValue('core', 'shareapi_default_expire_date', 'yes');
+ \OCP\Config::setAppValue('core', 'shareapi_enforce_expire_date', 'yes');
+
+ $dateWithinRange = new \DateTime();
+ $dateWithinRange->add(new \DateInterval('P5D'));
+ $dateOutOfRange = new \DateTime();
+ $dateOutOfRange->add(new \DateInterval('P8D'));
+
+ $result = \OCP\Share::shareItem('folder', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_LINK,
+ null, 1);
+
+ // share was successful?
+ $this->assertTrue(is_string($result));
+
+ $items = \OCP\Share::getItemShared('file', null);
+
+ // make sure that we found a link share
+ $this->assertEquals(1, count($items));
+
+ $linkShare = reset($items);
+
+ // update expire date to a valid value
+ $params = array();
+ $params['id'] = $linkShare['id'];
+ $params['_put'] = array();
+ $params['_put']['expireDate'] = $dateWithinRange->format('Y-m-d');
+
+ $result = Share\Api::updateShare($params);
+
+ $this->assertTrue($result->succeeded());
+
+ $items = \OCP\Share::getItemShared('file', $linkShare['file_source']);
+
+ $updatedLinkShare = reset($items);
+
+ // date should be changed
+ $this->assertTrue(is_array($updatedLinkShare));
+ $this->assertEquals($dateWithinRange->format('Y-m-d') . ' 00:00:00', $updatedLinkShare['expiration']);
+
+ // update expire date to a value out of range
+ $params = array();
+ $params['id'] = $linkShare['id'];
+ $params['_put'] = array();
+ $params['_put']['expireDate'] = $dateOutOfRange->format('Y-m-d');
+
+ $result = Share\Api::updateShare($params);
+
+ $this->assertFalse($result->succeeded());
+
+ $items = \OCP\Share::getItemShared('file', $linkShare['file_source']);
+
+ $updatedLinkShare = reset($items);
+
+ // date shouldn't be changed
+ $this->assertTrue(is_array($updatedLinkShare));
+ $this->assertEquals($dateWithinRange->format('Y-m-d') . ' 00:00:00', $updatedLinkShare['expiration']);
+
+ // cleanup
+ \OCP\Config::setAppValue('core', 'shareapi_default_expire_date', 'no');
+ \OCP\Config::setAppValue('core', 'shareapi_enforce_expire_date', 'no');
+ \OCP\Share::unshare('file', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_LINK, null);
+
+ }
+
+ /**
+ * @medium
* @depends testCreateShare
*/
function testDeleteShare() {
@@ -1158,7 +1230,7 @@ class Test_Files_Sharing_Api extends Test_Files_Sharing_Base {
$result = \OCP\Share::shareItem('file', $info->getId(), \OCP\Share::SHARE_TYPE_USER, \Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER2, 31);
$this->assertTrue($result);
- $result = \OCP\Share::setExpirationDate('file', $info->getId() , $expireDate);
+ $result = \OCP\Share::setExpirationDate('file', $info->getId() , $expireDate, $now);
$this->assertTrue($result);
//manipulate stime so that both shares are older then the default expire date
diff --git a/apps/files_sharing/tests/update.php b/apps/files_sharing/tests/update.php
index 86b92b69616..d3555cc2ee3 100644
--- a/apps/files_sharing/tests/update.php
+++ b/apps/files_sharing/tests/update.php
@@ -176,6 +176,7 @@ class Test_Files_Sharing_Update_Routine extends Test_Files_Sharing_Base {
array(\OCP\Share::SHARE_TYPE_USER, 'folder', 'user2', 'admin', '/foo2'),
array(\OCP\Share::SHARE_TYPE_USER, 'file', 'user3', 'admin', '/foo3'),
array(\OCP\Share::SHARE_TYPE_USER, 'folder', 'user4', 'admin', '/foo4'),
+ array(\OCP\Share::SHARE_TYPE_USER, 'folder', 'user4', 'admin', "/foo'4"),
array(\OCP\Share::SHARE_TYPE_LINK, 'file', 'user1', 'admin', '/ShouldNotChange'),
array(\OCP\Share::SHARE_TYPE_CONTACT, 'contact', 'admin', 'user1', '/ShouldNotChange'),
diff --git a/apps/files_versions/appinfo/app.php b/apps/files_versions/appinfo/app.php
index 371162cd16f..8c517d4d0ff 100644
--- a/apps/files_versions/appinfo/app.php
+++ b/apps/files_versions/appinfo/app.php
@@ -8,9 +8,4 @@ OC::$CLASSPATH['OCA\Files_Versions\Capabilities'] = 'files_versions/lib/capabili
OCP\Util::addscript('files_versions', 'versions');
OCP\Util::addStyle('files_versions', 'versions');
-// Listen to write signals
-OCP\Util::connectHook('OC_Filesystem', 'write', "OCA\Files_Versions\Hooks", "write_hook");
-// Listen to delete and rename signals
-OCP\Util::connectHook('OC_Filesystem', 'post_delete', "OCA\Files_Versions\Hooks", "remove_hook");
-OCP\Util::connectHook('OC_Filesystem', 'delete', "OCA\Files_Versions\Hooks", "pre_remove_hook");
-OCP\Util::connectHook('OC_Filesystem', 'rename', "OCA\Files_Versions\Hooks", "rename_hook");
+\OCA\Files_Versions\Hooks::connectHooks();
diff --git a/apps/files_versions/lib/hooks.php b/apps/files_versions/lib/hooks.php
index 990f1403e8d..1a584232ba7 100644
--- a/apps/files_versions/lib/hooks.php
+++ b/apps/files_versions/lib/hooks.php
@@ -14,6 +14,16 @@ namespace OCA\Files_Versions;
class Hooks {
+ public static function connectHooks() {
+ // Listen to write signals
+ \OCP\Util::connectHook('OC_Filesystem', 'write', "OCA\Files_Versions\Hooks", "write_hook");
+ // Listen to delete and rename signals
+ \OCP\Util::connectHook('OC_Filesystem', 'post_delete', "OCA\Files_Versions\Hooks", "remove_hook");
+ \OCP\Util::connectHook('OC_Filesystem', 'delete', "OCA\Files_Versions\Hooks", "pre_remove_hook");
+ \OCP\Util::connectHook('OC_Filesystem', 'rename', "OCA\Files_Versions\Hooks", "rename_hook");
+ \OCP\Util::connectHook('OC_Filesystem', 'copy', "OCA\Files_Versions\Hooks", "copy_hook");
+ }
+
/**
* listen to write event.
*/
@@ -69,7 +79,25 @@ class Hooks {
$oldpath = $params['oldpath'];
$newpath = $params['newpath'];
if($oldpath<>'' && $newpath<>'') {
- Storage::rename( $oldpath, $newpath );
+ Storage::renameOrCopy($oldpath, $newpath, 'rename');
+ }
+ }
+ }
+
+ /**
+ * copy versions of copied files
+ * @param array $params array with oldpath and newpath
+ *
+ * This function is connected to the copy signal of OC_Filesystem and copies the
+ * the stored versions to the new location
+ */
+ public static function copy_hook($params) {
+
+ if (\OCP\App::isEnabled('files_versions')) {
+ $oldpath = $params['oldpath'];
+ $newpath = $params['newpath'];
+ if($oldpath<>'' && $newpath<>'') {
+ Storage::renameOrCopy($oldpath, $newpath, 'copy');
}
}
}
diff --git a/apps/files_versions/lib/versions.php b/apps/files_versions/lib/versions.php
index 2e048416c11..a9d51b2c58b 100644
--- a/apps/files_versions/lib/versions.php
+++ b/apps/files_versions/lib/versions.php
@@ -174,9 +174,12 @@ class Storage {
}
/**
- * rename versions of a file
+ * rename or copy versions of a file
+ * @param string $old_path
+ * @param string $new_path
+ * @param string $operation can be 'copy' or 'rename'
*/
- public static function rename($old_path, $new_path) {
+ public static function renameOrCopy($old_path, $new_path, $operation) {
list($uid, $oldpath) = self::getUidAndFilename($old_path);
list($uidn, $newpath) = self::getUidAndFilename($new_path);
$versions_view = new \OC\Files\View('/'.$uid .'/files_versions');
@@ -188,18 +191,21 @@ class Storage {
return self::store($new_path);
}
- self::expire($newpath);
-
if ( $files_view->is_dir($oldpath) && $versions_view->is_dir($oldpath) ) {
- $versions_view->rename($oldpath, $newpath);
+ $versions_view->$operation($oldpath, $newpath);
} else if ( ($versions = Storage::getVersions($uid, $oldpath)) ) {
// create missing dirs if necessary
self::createMissingDirectories($newpath, new \OC\Files\View('/'. $uidn));
foreach ($versions as $v) {
- $versions_view->rename($oldpath.'.v'.$v['version'], $newpath.'.v'.$v['version']);
+ $versions_view->$operation($oldpath.'.v'.$v['version'], $newpath.'.v'.$v['version']);
}
}
+
+ if (!$files_view->is_dir($newpath)) {
+ self::expire($newpath);
+ }
+
}
/**
@@ -254,34 +260,46 @@ class Storage {
public static function getVersions($uid, $filename, $userFullPath = '') {
$versions = array();
// fetch for old versions
- $view = new \OC\Files\View('/' . $uid . '/' . self::VERSIONS_ROOT);
+ $view = new \OC\Files\View('/' . $uid . '/');
$pathinfo = pathinfo($filename);
+ $versionedFile = $pathinfo['basename'];
- $files = $view->getDirectoryContent($pathinfo['dirname']);
+ $dir = self::VERSIONS_ROOT . '/' . $pathinfo['dirname'];
- $versionedFile = $pathinfo['basename'];
+ $dirContent = false;
+ if ($view->is_dir($dir)) {
+ $dirContent = $view->opendir($dir);
+ }
- foreach ($files as $file) {
- if ($file['type'] === 'file') {
- $pos = strrpos($file['path'], '.v');
- $currentFile = substr($file['name'], 0, strrpos($file['name'], '.v'));
- if ($currentFile === $versionedFile) {
- $version = substr($file['path'], $pos + 2);
- $key = $version . '#' . $filename;
- $versions[$key]['cur'] = 0;
- $versions[$key]['version'] = $version;
- $versions[$key]['humanReadableTimestamp'] = self::getHumanReadableTimestamp($version);
- if (empty($userFullPath)) {
- $versions[$key]['preview'] = '';
- } else {
- $versions[$key]['preview'] = \OCP\Util::linkToRoute('core_ajax_versions_preview', array('file' => $userFullPath, 'version' => $version));
+ if ($dirContent === false) {
+ return $versions;
+ }
+
+ if (is_resource($dirContent)) {
+ while (($entryName = readdir($dirContent)) !== false) {
+ if (!\OC\Files\Filesystem::isIgnoredDir($entryName)) {
+ $pathparts = pathinfo($entryName);
+ $filename = $pathparts['filename'];
+ if ($filename === $versionedFile) {
+ $pathparts = pathinfo($entryName);
+ $timestamp = substr($pathparts['extension'], 1);
+ $filename = $pathparts['filename'];
+ $key = $timestamp . '#' . $filename;
+ $versions[$key]['version'] = $timestamp;
+ $versions[$key]['humanReadableTimestamp'] = self::getHumanReadableTimestamp($timestamp);
+ if (empty($userFullPath)) {
+ $versions[$key]['preview'] = '';
+ } else {
+ $versions[$key]['preview'] = \OCP\Util::linkToRoute('core_ajax_versions_preview', array('file' => $userFullPath, 'version' => $timestamp));
+ }
+ $versions[$key]['path'] = $filename;
+ $versions[$key]['name'] = $versionedFile;
+ $versions[$key]['size'] = $view->filesize($dir . '/' . $entryName);
}
- $versions[$key]['path'] = $filename;
- $versions[$key]['name'] = $versionedFile;
- $versions[$key]['size'] = $file['size'];
}
}
+ closedir($dirContent);
}
// sort with newest version first
diff --git a/apps/files_versions/tests/versions.php b/apps/files_versions/tests/versions.php
index aa66faffcbf..03432276358 100644
--- a/apps/files_versions/tests/versions.php
+++ b/apps/files_versions/tests/versions.php
@@ -20,6 +20,7 @@
*
*/
+require_once __DIR__ . '/../appinfo/app.php';
require_once __DIR__ . '/../lib/versions.php';
/**
@@ -28,6 +29,32 @@ require_once __DIR__ . '/../lib/versions.php';
*/
class Test_Files_Versioning extends \PHPUnit_Framework_TestCase {
+ const TEST_VERSIONS_USER = 'test-versions-user';
+ const USERS_VERSIONS_ROOT = '/test-versions-user/files_versions';
+
+ private $rootView;
+
+ public static function setUpBeforeClass() {
+ // create test user
+ self::loginHelper(self::TEST_VERSIONS_USER, true);
+ }
+
+ public static function tearDownAfterClass() {
+ // cleanup test user
+ \OC_User::deleteUser(self::TEST_VERSIONS_USER);
+ }
+
+ function setUp() {
+ self::loginHelper(self::TEST_VERSIONS_USER);
+ $this->rootView = new \OC\Files\View();
+ if (!$this->rootView->file_exists(self::USERS_VERSIONS_ROOT)) {
+ $this->rootView->mkdir(self::USERS_VERSIONS_ROOT);
+ }
+ }
+
+ function tearDown() {
+ $this->rootView->deleteAll(self::USERS_VERSIONS_ROOT);
+ }
/**
* @medium
@@ -176,6 +203,87 @@ class Test_Files_Versioning extends \PHPUnit_Framework_TestCase {
);
}
+ function testRename() {
+
+ \OC\Files\Filesystem::file_put_contents("test.txt", "test file");
+
+ $t1 = time();
+ // second version is two weeks older, this way we make sure that no
+ // version will be expired
+ $t2 = $t1 - 60 * 60 * 24 * 14;
+
+ // create some versions
+ $v1 = self::USERS_VERSIONS_ROOT . '/test.txt.v' . $t1;
+ $v2 = self::USERS_VERSIONS_ROOT . '/test.txt.v' . $t2;
+ $v1Renamed = self::USERS_VERSIONS_ROOT . '/test2.txt.v' . $t1;
+ $v2Renamed = self::USERS_VERSIONS_ROOT . '/test2.txt.v' . $t2;
+
+ $this->rootView->file_put_contents($v1, 'version1');
+ $this->rootView->file_put_contents($v2, 'version2');
+
+ // execute rename hook of versions app
+ \OCA\Files_Versions\Storage::renameOrCopy("test.txt", "test2.txt", 'rename');
+
+ $this->assertFalse($this->rootView->file_exists($v1));
+ $this->assertFalse($this->rootView->file_exists($v2));
+
+ $this->assertTrue($this->rootView->file_exists($v1Renamed));
+ $this->assertTrue($this->rootView->file_exists($v2Renamed));
+
+ //cleanup
+ \OC\Files\Filesystem::unlink('test2.txt');
+ }
+
+ function testCopy() {
+
+ \OC\Files\Filesystem::file_put_contents("test.txt", "test file");
+
+ $t1 = time();
+ // second version is two weeks older, this way we make sure that no
+ // version will be expired
+ $t2 = $t1 - 60 * 60 * 24 * 14;
+
+ // create some versions
+ $v1 = self::USERS_VERSIONS_ROOT . '/test.txt.v' . $t1;
+ $v2 = self::USERS_VERSIONS_ROOT . '/test.txt.v' . $t2;
+ $v1Copied = self::USERS_VERSIONS_ROOT . '/test2.txt.v' . $t1;
+ $v2Copied = self::USERS_VERSIONS_ROOT . '/test2.txt.v' . $t2;
+
+ $this->rootView->file_put_contents($v1, 'version1');
+ $this->rootView->file_put_contents($v2, 'version2');
+
+ // execute copy hook of versions app
+ \OCA\Files_Versions\Storage::renameOrCopy("test.txt", "test2.txt", 'copy');
+
+ $this->assertTrue($this->rootView->file_exists($v1));
+ $this->assertTrue($this->rootView->file_exists($v2));
+
+ $this->assertTrue($this->rootView->file_exists($v1Copied));
+ $this->assertTrue($this->rootView->file_exists($v2Copied));
+
+ //cleanup
+ \OC\Files\Filesystem::unlink('test.txt');
+ \OC\Files\Filesystem::unlink('test2.txt');
+ }
+
+ /**
+ * @param string $user
+ * @param bool $create
+ * @param bool $password
+ */
+ public static function loginHelper($user, $create = false) {
+
+ if ($create) {
+ \OC_User::createUser($user, $user);
+ }
+
+ \OC_Util::tearDownFS();
+ \OC_User::setUserId('');
+ \OC\Files\Filesystem::tearDown();
+ \OC_User::setUserId($user);
+ \OC_Util::setupFS($user);
+ }
+
}
// extend the original class to make it possible to test protected methods