Merge branch 'master' into memcache-public

This commit is contained in:
Robin Appelman 2014-01-22 13:19:49 +01:00
commit 02aa44d055
56 changed files with 711 additions and 241 deletions

View File

@ -34,6 +34,7 @@ if (empty($_POST['dirToken'])) {
// resolve reshares // resolve reshares
$rootLinkItem = OCP\Share::resolveReShare($linkItem); $rootLinkItem = OCP\Share::resolveReShare($linkItem);
OCP\JSON::checkUserExists($rootLinkItem['uid_owner']);
// Setup FS with owner // Setup FS with owner
OC_Util::tearDownFS(); OC_Util::tearDownFS();
OC_Util::setupFS($rootLinkItem['uid_owner']); OC_Util::setupFS($rootLinkItem['uid_owner']);

View File

@ -27,6 +27,8 @@ var FileList={
Files.setupDragAndDrop(); Files.setupDragAndDrop();
} }
FileList.updateFileSummary(); FileList.updateFileSummary();
procesSelection();
$fileList.trigger(jQuery.Event("updated")); $fileList.trigger(jQuery.Event("updated"));
}, },
createRow:function(type, name, iconurl, linktarget, size, lastModified, permissions) { createRow:function(type, name, iconurl, linktarget, size, lastModified, permissions) {
@ -300,7 +302,10 @@ var FileList={
}, },
remove:function(name){ remove:function(name){
var fileEl = FileList.findFileEl(name); var fileEl = FileList.findFileEl(name);
fileEl.find('td.filename').draggable('destroy'); if (fileEl.data('permissions') & OC.PERMISSION_DELETE) {
// file is only draggable when delete permissions are set
fileEl.find('td.filename').draggable('destroy');
}
fileEl.remove(); fileEl.remove();
FileList.updateFileSummary(); FileList.updateFileSummary();
if ( ! $('tr[data-file]').exists() ) { if ( ! $('tr[data-file]').exists() ) {

View File

@ -612,11 +612,12 @@ function procesSelection() {
return el.type==='dir'; return el.type==='dir';
}); });
if (selectedFiles.length === 0 && selectedFolders.length === 0) { if (selectedFiles.length === 0 && selectedFolders.length === 0) {
$('#headerName>span.name').text(t('files','Name')); $('#headerName span.name').text(t('files','Name'));
$('#headerSize').text(t('files','Size')); $('#headerSize').text(t('files','Size'));
$('#modified').text(t('files','Modified')); $('#modified').text(t('files','Modified'));
$('table').removeClass('multiselect'); $('table').removeClass('multiselect');
$('.selectedActions').hide(); $('.selectedActions').hide();
$('#select_all').removeAttr('checked');
} }
else { else {
$('.selectedActions').show(); $('.selectedActions').show();
@ -719,7 +720,7 @@ Files.lazyLoadPreview = function(path, mime, ready, width, height, etag) {
console.warn('Files.lazyLoadPreview(): missing etag argument'); console.warn('Files.lazyLoadPreview(): missing etag argument');
} }
if ( $('#publicUploadButtonMock').length ) { if ( $('#public_upload').length ) {
urlSpec.t = $('#dirToken').val(); urlSpec.t = $('#dirToken').val();
previewURL = OC.Router.generate('core_ajax_public_preview', urlSpec); previewURL = OC.Router.generate('core_ajax_public_preview', urlSpec);
} else { } else {

View File

@ -1,6 +1,10 @@
<div class="crumb <?php if(!count($_["breadcrumb"])) p('last');?>" data-dir=''> <div class="crumb <?php if(!count($_["breadcrumb"])) p('last');?>" data-dir=''>
<a href="<?php print_unescaped($_['baseURL']); ?>"> <a href="<?php print_unescaped($_['baseURL']); ?>">
<img src="<?php print_unescaped(OCP\image_path('core', 'places/home.svg'));?>" class="svg" /> <?php if(isset($_['rootBreadCrumb'])):
echo $_['rootBreadCrumb'];
else:?>
<img src="<?php print_unescaped(OCP\image_path('core', 'places/home.svg'));?>" class="svg" />
<?php endif;?>
</a> </a>
</div> </div>
<?php for($i=0; $i<count($_["breadcrumb"]); $i++): <?php for($i=0; $i<count($_["breadcrumb"]); $i++):

View File

@ -18,7 +18,7 @@ $totalsize = 0; ?>
data-size="<?php p($file['size']);?>" data-size="<?php p($file['size']);?>"
data-etag="<?php p($file['etag']);?>" data-etag="<?php p($file['etag']);?>"
data-permissions="<?php p($file['permissions']); ?>"> data-permissions="<?php p($file['permissions']); ?>">
<?php if($file['isPreviewAvailable']): ?> <?php if(isset($file['isPreviewAvailable']) and $file['isPreviewAvailable']): ?>
<td class="filename svg preview-icon" <td class="filename svg preview-icon"
<?php else: ?> <?php else: ?>
<td class="filename svg" <td class="filename svg"

View File

@ -6,6 +6,7 @@ if (OC::$CLI) {
if (count($argv) === 2) { if (count($argv) === 2) {
$file = $argv[1]; $file = $argv[1];
list(, $user) = explode('/', $file); list(, $user) = explode('/', $file);
OCP\JSON::checkUserExists($owner);
OC_Util::setupFS($user); OC_Util::setupFS($user);
$view = new \OC\Files\View(''); $view = new \OC\Files\View('');
/** /**

View File

@ -2,11 +2,15 @@
<info> <info>
<id>files_encryption</id> <id>files_encryption</id>
<name>Encryption</name> <name>Encryption</name>
<description>The new ownCloud 5 files encryption system. After the app was enabled you need to re-login to initialize your encryption keys.</description> <description>The ownCloud files encryption system provides server side-encryption. After the app was enabled you need to re-login to initialize your encryption keys.</description>
<licence>AGPL</licence> <licence>AGPL</licence>
<author>Sam Tuke, Bjoern Schiessle, Florin Peter</author> <author>Sam Tuke, Bjoern Schiessle, Florin Peter</author>
<require>4</require> <require>4</require>
<shipped>true</shipped> <shipped>true</shipped>
<documentation>
<user>http://doc.owncloud.org/server/6.0/user_manual/files/encryption.html</user>
<admin>http://doc.owncloud.org/server/6.0/admin_manual/configuration/configuration_encryption.html</admin>
</documentation>
<rememberlogin>false</rememberlogin> <rememberlogin>false</rememberlogin>
<types> <types>
<filesystem/> <filesystem/>

View File

@ -255,8 +255,8 @@ class Proxy extends \OC_FileProxy {
// split the path parts // split the path parts
$pathParts = explode('/', $path); $pathParts = explode('/', $path);
// FIXME: handling for /userId/cache used by webdav for chunking. The cache chunks are NOT encrypted // don't try to encrypt/decrypt cache chunks or files in the trash bin
if (isset($pathParts[2]) && $pathParts[2] === 'cache') { if (isset($pathParts[2]) && ($pathParts[2] === 'cache' || $pathParts[2] === 'files_trashbin')) {
return $result; return $result;
} }

View File

@ -155,7 +155,7 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase {
*/ */
function testSymmetricStreamEncryptShortFileContent() { function testSymmetricStreamEncryptShortFileContent() {
$filename = 'tmp-' . time() . '.test'; $filename = 'tmp-' . uniqid() . '.test';
$util = new Encryption\Util(new \OC_FilesystemView(), $this->userId); $util = new Encryption\Util(new \OC_FilesystemView(), $this->userId);
@ -214,7 +214,7 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase {
function testSymmetricStreamEncryptLongFileContent() { function testSymmetricStreamEncryptLongFileContent() {
// Generate a a random filename // Generate a a random filename
$filename = 'tmp-' . time() . '.test'; $filename = 'tmp-' . uniqid() . '.test';
$util = new Encryption\Util(new \OC_FilesystemView(), $this->userId); $util = new Encryption\Util(new \OC_FilesystemView(), $this->userId);
@ -297,7 +297,7 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase {
*/ */
function testSymmetricStreamDecryptShortFileContent() { function testSymmetricStreamDecryptShortFileContent() {
$filename = 'tmp-' . time(); $filename = 'tmp-' . uniqid();
// Save long data as encrypted file using stream wrapper // Save long data as encrypted file using stream wrapper
$cryptedFile = file_put_contents('crypt:///'. $this->userId . '/files/' . $filename, $this->dataShort); $cryptedFile = file_put_contents('crypt:///'. $this->userId . '/files/' . $filename, $this->dataShort);
@ -327,7 +327,7 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase {
*/ */
function testSymmetricStreamDecryptLongFileContent() { function testSymmetricStreamDecryptLongFileContent() {
$filename = 'tmp-' . time(); $filename = 'tmp-' . uniqid();
// Save long data as encrypted file using stream wrapper // Save long data as encrypted file using stream wrapper
$cryptedFile = file_put_contents('crypt:///' . $this->userId . '/files/' . $filename, $this->dataLong); $cryptedFile = file_put_contents('crypt:///' . $this->userId . '/files/' . $filename, $this->dataLong);
@ -418,7 +418,7 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase {
*/ */
function testRenameFile() { function testRenameFile() {
$filename = 'tmp-' . time(); $filename = 'tmp-' . uniqid();
// Save long data as encrypted file using stream wrapper // Save long data as encrypted file using stream wrapper
$cryptedFile = file_put_contents('crypt:///' . $this->userId . '/files/' . $filename, $this->dataLong); $cryptedFile = file_put_contents('crypt:///' . $this->userId . '/files/' . $filename, $this->dataLong);
@ -431,7 +431,7 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase {
$this->assertEquals($this->dataLong, $decrypt); $this->assertEquals($this->dataLong, $decrypt);
$newFilename = 'tmp-new-' . time(); $newFilename = 'tmp-new-' . uniqid();
$view = new \OC\Files\View('/' . $this->userId . '/files'); $view = new \OC\Files\View('/' . $this->userId . '/files');
$view->rename($filename, $newFilename); $view->rename($filename, $newFilename);
@ -449,7 +449,7 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase {
*/ */
function testMoveFileIntoFolder() { function testMoveFileIntoFolder() {
$filename = 'tmp-' . time(); $filename = 'tmp-' . uniqid();
// Save long data as encrypted file using stream wrapper // Save long data as encrypted file using stream wrapper
$cryptedFile = file_put_contents('crypt:///' . $this->userId . '/files/' . $filename, $this->dataLong); $cryptedFile = file_put_contents('crypt:///' . $this->userId . '/files/' . $filename, $this->dataLong);
@ -462,8 +462,8 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase {
$this->assertEquals($this->dataLong, $decrypt); $this->assertEquals($this->dataLong, $decrypt);
$newFolder = '/newfolder' . time(); $newFolder = '/newfolder' . uniqid();
$newFilename = 'tmp-new-' . time(); $newFilename = 'tmp-new-' . uniqid();
$view = new \OC\Files\View('/' . $this->userId . '/files'); $view = new \OC\Files\View('/' . $this->userId . '/files');
$view->mkdir($newFolder); $view->mkdir($newFolder);
$view->rename($filename, $newFolder . '/' . $newFilename); $view->rename($filename, $newFolder . '/' . $newFilename);
@ -484,8 +484,8 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase {
$view = new \OC\Files\View('/' . $this->userId . '/files'); $view = new \OC\Files\View('/' . $this->userId . '/files');
$filename = '/tmp-' . time(); $filename = '/tmp-' . uniqid();
$folder = '/folder' . time(); $folder = '/folder' . uniqid();
$view->mkdir($folder); $view->mkdir($folder);
@ -500,7 +500,7 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase {
$this->assertEquals($this->dataLong, $decrypt); $this->assertEquals($this->dataLong, $decrypt);
$newFolder = '/newfolder/subfolder' . time(); $newFolder = '/newfolder/subfolder' . uniqid();
$view->mkdir('/newfolder'); $view->mkdir('/newfolder');
$view->rename($folder, $newFolder); $view->rename($folder, $newFolder);
@ -519,7 +519,7 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase {
* @medium * @medium
*/ */
function testChangePassphrase() { function testChangePassphrase() {
$filename = 'tmp-' . time(); $filename = 'tmp-' . uniqid();
// Save long data as encrypted file using stream wrapper // Save long data as encrypted file using stream wrapper
$cryptedFile = file_put_contents('crypt:///' . $this->userId . '/files/' . $filename, $this->dataLong); $cryptedFile = file_put_contents('crypt:///' . $this->userId . '/files/' . $filename, $this->dataLong);
@ -557,7 +557,7 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase {
*/ */
function testViewFilePutAndGetContents() { function testViewFilePutAndGetContents() {
$filename = '/tmp-' . time(); $filename = '/tmp-' . uniqid();
$view = new \OC\Files\View('/' . $this->userId . '/files'); $view = new \OC\Files\View('/' . $this->userId . '/files');
// Save short data as encrypted file using stream wrapper // Save short data as encrypted file using stream wrapper
@ -590,7 +590,7 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase {
* @large * @large
*/ */
function testTouchExistingFile() { function testTouchExistingFile() {
$filename = '/tmp-' . time(); $filename = '/tmp-' . uniqid();
$view = new \OC\Files\View('/' . $this->userId . '/files'); $view = new \OC\Files\View('/' . $this->userId . '/files');
// Save short data as encrypted file using stream wrapper // Save short data as encrypted file using stream wrapper
@ -614,7 +614,7 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase {
* @medium * @medium
*/ */
function testTouchFile() { function testTouchFile() {
$filename = '/tmp-' . time(); $filename = '/tmp-' . uniqid();
$view = new \OC\Files\View('/' . $this->userId . '/files'); $view = new \OC\Files\View('/' . $this->userId . '/files');
$view->touch($filename); $view->touch($filename);
@ -638,7 +638,7 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase {
* @medium * @medium
*/ */
function testFopenFile() { function testFopenFile() {
$filename = '/tmp-' . time(); $filename = '/tmp-' . uniqid();
$view = new \OC\Files\View('/' . $this->userId . '/files'); $view = new \OC\Files\View('/' . $this->userId . '/files');
// Save short data as encrypted file using stream wrapper // Save short data as encrypted file using stream wrapper

View File

@ -143,7 +143,7 @@ class Test_Encryption_Keymanager extends \PHPUnit_Framework_TestCase {
$key = $this->randomKey; $key = $this->randomKey;
$file = 'unittest-' . time() . '.txt'; $file = 'unittest-' . uniqid() . '.txt';
$util = new Encryption\Util($this->view, $this->userId); $util = new Encryption\Util($this->view, $this->userId);
@ -196,7 +196,7 @@ class Test_Encryption_Keymanager extends \PHPUnit_Framework_TestCase {
function testRecursiveDelShareKeys() { function testRecursiveDelShareKeys() {
// generate filename // generate filename
$filename = '/tmp-' . time() . '.txt'; $filename = '/tmp-' . uniqid() . '.txt';
// create folder structure // create folder structure
$this->view->mkdir('/'.Test_Encryption_Keymanager::TEST_USER.'/files/folder1'); $this->view->mkdir('/'.Test_Encryption_Keymanager::TEST_USER.'/files/folder1');

View File

@ -80,7 +80,7 @@ class Test_Encryption_Proxy extends \PHPUnit_Framework_TestCase {
// init short data // init short data
$this->data = 'hats'; $this->data = 'hats';
$this->filename = 'enc_proxy_tests-' . time() . '.txt'; $this->filename = 'enc_proxy_tests-' . uniqid() . '.txt';
} }

View File

@ -99,7 +99,7 @@ class Test_Encryption_Stream extends \PHPUnit_Framework_TestCase {
} }
function testStreamOptions() { function testStreamOptions() {
$filename = '/tmp-' . time(); $filename = '/tmp-' . uniqid();
$view = new \OC\Files\View('/' . $this->userId . '/files'); $view = new \OC\Files\View('/' . $this->userId . '/files');
// Save short data as encrypted file using stream wrapper // Save short data as encrypted file using stream wrapper
@ -122,7 +122,7 @@ class Test_Encryption_Stream extends \PHPUnit_Framework_TestCase {
} }
function testStreamSetBlocking() { function testStreamSetBlocking() {
$filename = '/tmp-' . time(); $filename = '/tmp-' . uniqid();
$view = new \OC\Files\View('/' . $this->userId . '/files'); $view = new \OC\Files\View('/' . $this->userId . '/files');
// Save short data as encrypted file using stream wrapper // Save short data as encrypted file using stream wrapper
@ -144,7 +144,7 @@ class Test_Encryption_Stream extends \PHPUnit_Framework_TestCase {
* @medium * @medium
*/ */
function testStreamSetTimeout() { function testStreamSetTimeout() {
$filename = '/tmp-' . time(); $filename = '/tmp-' . uniqid();
$view = new \OC\Files\View('/' . $this->userId . '/files'); $view = new \OC\Files\View('/' . $this->userId . '/files');
// Save short data as encrypted file using stream wrapper // Save short data as encrypted file using stream wrapper
@ -163,7 +163,7 @@ class Test_Encryption_Stream extends \PHPUnit_Framework_TestCase {
} }
function testStreamSetWriteBuffer() { function testStreamSetWriteBuffer() {
$filename = '/tmp-' . time(); $filename = '/tmp-' . uniqid();
$view = new \OC\Files\View('/' . $this->userId . '/files'); $view = new \OC\Files\View('/' . $this->userId . '/files');
// Save short data as encrypted file using stream wrapper // Save short data as encrypted file using stream wrapper
@ -187,9 +187,9 @@ class Test_Encryption_Stream extends \PHPUnit_Framework_TestCase {
*/ */
function testStreamFromLocalFile() { function testStreamFromLocalFile() {
$filename = '/' . $this->userId . '/files/' . 'tmp-' . time().'.txt'; $filename = '/' . $this->userId . '/files/' . 'tmp-' . uniqid().'.txt';
$tmpFilename = "/tmp/" . time() . ".txt"; $tmpFilename = "/tmp/" . uniqid() . ".txt";
// write an encrypted file // write an encrypted file
$cryptedFile = $this->view->file_put_contents($filename, $this->dataShort); $cryptedFile = $this->view->file_put_contents($filename, $this->dataShort);

View File

@ -119,7 +119,7 @@ class Test_Encryption_Trashbin extends \PHPUnit_Framework_TestCase {
function testDeleteFile() { function testDeleteFile() {
// generate filename // generate filename
$filename = 'tmp-' . time() . '.txt'; $filename = 'tmp-' . uniqid() . '.txt';
// save file with content // save file with content
$cryptedFile = file_put_contents('crypt:///' .\Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1. '/files/'. $filename, $this->dataShort); $cryptedFile = file_put_contents('crypt:///' .\Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1. '/files/'. $filename, $this->dataShort);
@ -223,7 +223,7 @@ class Test_Encryption_Trashbin extends \PHPUnit_Framework_TestCase {
function testPermanentDeleteFile() { function testPermanentDeleteFile() {
// generate filename // generate filename
$filename = 'tmp-' . time() . '.txt'; $filename = 'tmp-' . uniqid() . '.txt';
// save file with content // save file with content
$cryptedFile = file_put_contents('crypt:///' .$this->userId. '/files/' . $filename, $this->dataShort); $cryptedFile = file_put_contents('crypt:///' .$this->userId. '/files/' . $filename, $this->dataShort);

View File

@ -142,8 +142,8 @@ class Test_Encryption_Util extends \PHPUnit_Framework_TestCase {
self::loginHelper($this->userId); self::loginHelper($this->userId);
$unencryptedFile = '/tmpUnencrypted-' . time() . '.txt'; $unencryptedFile = '/tmpUnencrypted-' . uniqid() . '.txt';
$encryptedFile = '/tmpEncrypted-' . time() . '.txt'; $encryptedFile = '/tmpEncrypted-' . uniqid() . '.txt';
// Disable encryption proxy to write a unencrypted file // Disable encryption proxy to write a unencrypted file
$proxyStatus = \OC_FileProxy::$enabled; $proxyStatus = \OC_FileProxy::$enabled;
@ -254,7 +254,7 @@ class Test_Encryption_Util extends \PHPUnit_Framework_TestCase {
\OC_User::setUserId(\Test_Encryption_Util::TEST_ENCRYPTION_UTIL_USER1); \OC_User::setUserId(\Test_Encryption_Util::TEST_ENCRYPTION_UTIL_USER1);
$filename = '/tmp-' . time() . '.test'; $filename = '/tmp-' . uniqid() . '.test';
// Disable encryption proxy to prevent recursive calls // Disable encryption proxy to prevent recursive calls
$proxyStatus = \OC_FileProxy::$enabled; $proxyStatus = \OC_FileProxy::$enabled;
@ -282,7 +282,7 @@ class Test_Encryption_Util extends \PHPUnit_Framework_TestCase {
function testGetFileSize() { function testGetFileSize() {
\Test_Encryption_Util::loginHelper(\Test_Encryption_Util::TEST_ENCRYPTION_UTIL_USER1); \Test_Encryption_Util::loginHelper(\Test_Encryption_Util::TEST_ENCRYPTION_UTIL_USER1);
$filename = 'tmp-' . time(); $filename = 'tmp-' . uniqid();
$externalFilename = '/' . $this->userId . '/files/' . $filename; $externalFilename = '/' . $this->userId . '/files/' . $filename;
// Test for 0 byte files // Test for 0 byte files
@ -318,7 +318,7 @@ class Test_Encryption_Util extends \PHPUnit_Framework_TestCase {
function testEncryptAll() { function testEncryptAll() {
$filename = "/encryptAll" . time() . ".txt"; $filename = "/encryptAll" . uniqid() . ".txt";
$util = new Encryption\Util($this->view, $this->userId); $util = new Encryption\Util($this->view, $this->userId);
// disable encryption to upload a unencrypted file // disable encryption to upload a unencrypted file
@ -350,7 +350,7 @@ class Test_Encryption_Util extends \PHPUnit_Framework_TestCase {
function testDecryptAll() { function testDecryptAll() {
$filename = "/decryptAll" . time() . ".txt"; $filename = "/decryptAll" . uniqid() . ".txt";
$util = new Encryption\Util($this->view, $this->userId); $util = new Encryption\Util($this->view, $this->userId);
$this->view->file_put_contents($this->userId . '/files/' . $filename, $this->dataShort); $this->view->file_put_contents($this->userId . '/files/' . $filename, $this->dataShort);

View File

@ -113,7 +113,7 @@ class Test_Encryption_Webdav extends \PHPUnit_Framework_TestCase {
function testWebdavPUT() { function testWebdavPUT() {
// generate filename // generate filename
$filename = '/tmp-' . time() . '.txt'; $filename = '/tmp-' . uniqid() . '.txt';
// set server vars // set server vars
$_SERVER['REQUEST_METHOD'] = 'OPTIONS'; $_SERVER['REQUEST_METHOD'] = 'OPTIONS';

View File

@ -23,9 +23,12 @@ $(document).ready(function() {
$(token).val(result.access_token); $(token).val(result.access_token);
$(token_secret).val(result.access_token_secret); $(token_secret).val(result.access_token_secret);
$(configured).val('true'); $(configured).val('true');
OC.MountConfig.saveStorage(tr); OC.MountConfig.saveStorage(tr, function(status) {
$(tr).find('.configuration input').attr('disabled', 'disabled'); if (status) {
$(tr).find('.configuration').append('<span id="access" style="padding-left:0.5em;">'+t('files_external', 'Access granted')+'</span>'); $(tr).find('.configuration input').attr('disabled', 'disabled');
$(tr).find('.configuration').append('<span id="access" style="padding-left:0.5em;">'+t('files_external', 'Access granted')+'</span>');
}
});
} else { } else {
OC.dialogs.alert(result.data.message, t('files_external', 'Error configuring Dropbox storage')); OC.dialogs.alert(result.data.message, t('files_external', 'Error configuring Dropbox storage'));
} }
@ -77,7 +80,6 @@ $(document).ready(function() {
var tr = $(this).parent().parent(); var tr = $(this).parent().parent();
var app_key = $(this).parent().find('[data-parameter="app_key"]').val(); var app_key = $(this).parent().find('[data-parameter="app_key"]').val();
var app_secret = $(this).parent().find('[data-parameter="app_secret"]').val(); var app_secret = $(this).parent().find('[data-parameter="app_secret"]').val();
var statusSpan = $(tr).find('.status span');
if (app_key != '' && app_secret != '') { if (app_key != '' && app_secret != '') {
var tr = $(this).parent().parent(); var tr = $(this).parent().parent();
var configured = $(this).parent().find('[data-parameter="configured"]'); var configured = $(this).parent().find('[data-parameter="configured"]');
@ -88,10 +90,9 @@ $(document).ready(function() {
$(configured).val('false'); $(configured).val('false');
$(token).val(result.data.request_token); $(token).val(result.data.request_token);
$(token_secret).val(result.data.request_token_secret); $(token_secret).val(result.data.request_token_secret);
OC.MountConfig.saveStorage(tr); OC.MountConfig.saveStorage(tr, function() {
statusSpan.removeClass(); window.location = result.data.url;
statusSpan.addClass('waiting'); });
window.location = result.data.url;
} else { } else {
OC.dialogs.alert(result.data.message, t('files_external', 'Error configuring Dropbox storage')); OC.dialogs.alert(result.data.message, t('files_external', 'Error configuring Dropbox storage'));
} }

View File

@ -32,11 +32,14 @@ $(document).ready(function() {
if (result && result.status == 'success') { if (result && result.status == 'success') {
$(token).val(result.data.token); $(token).val(result.data.token);
$(configured).val('true'); $(configured).val('true');
OC.MountConfig.saveStorage(tr); OC.MountConfig.saveStorage(tr, function(status) {
$(tr).find('.configuration input').attr('disabled', 'disabled'); if (status) {
$(tr).find('.configuration').append($('<span/>') $(tr).find('.configuration input').attr('disabled', 'disabled');
.attr('id', 'access') $(tr).find('.configuration').append($('<span/>')
.text(t('files_external', 'Access granted'))); .attr('id', 'access')
.text(t('files_external', 'Access granted')));
}
});
} else { } else {
OC.dialogs.alert(result.data.message, OC.dialogs.alert(result.data.message,
t('files_external', 'Error configuring Google Drive storage') t('files_external', 'Error configuring Google Drive storage')
@ -99,7 +102,6 @@ $(document).ready(function() {
var configured = $(this).parent().find('[data-parameter="configured"]'); var configured = $(this).parent().find('[data-parameter="configured"]');
var client_id = $(this).parent().find('[data-parameter="client_id"]').val(); var client_id = $(this).parent().find('[data-parameter="client_id"]').val();
var client_secret = $(this).parent().find('[data-parameter="client_secret"]').val(); var client_secret = $(this).parent().find('[data-parameter="client_secret"]').val();
var statusSpan = $(tr).find('.status span');
if (client_id != '' && client_secret != '') { if (client_id != '' && client_secret != '') {
var token = $(this).parent().find('[data-parameter="token"]'); var token = $(this).parent().find('[data-parameter="token"]');
$.post(OC.filePath('files_external', 'ajax', 'google.php'), $.post(OC.filePath('files_external', 'ajax', 'google.php'),
@ -112,10 +114,9 @@ $(document).ready(function() {
if (result && result.status == 'success') { if (result && result.status == 'success') {
$(configured).val('false'); $(configured).val('false');
$(token).val('false'); $(token).val('false');
OC.MountConfig.saveStorage(tr); OC.MountConfig.saveStorage(tr, function(status) {
statusSpan.removeClass(); window.location = result.data.url;
statusSpan.addClass('waiting'); });
window.location = result.data.url;
} else { } else {
OC.dialogs.alert(result.data.message, OC.dialogs.alert(result.data.message,
t('files_external', 'Error configuring Google Drive storage') t('files_external', 'Error configuring Google Drive storage')

View File

@ -12,7 +12,7 @@ function updateStatus(statusEl, result){
} }
OC.MountConfig={ OC.MountConfig={
saveStorage:function(tr) { saveStorage:function(tr, callback) {
var mountPoint = $(tr).find('.mountPoint input').val(); var mountPoint = $(tr).find('.mountPoint input').val();
if (mountPoint == '') { if (mountPoint == '') {
return false; return false;
@ -84,9 +84,15 @@ OC.MountConfig={
}, },
success: function(result) { success: function(result) {
status = updateStatus(statusSpan, result); status = updateStatus(statusSpan, result);
if (callback) {
callback(status);
}
}, },
error: function(result){ error: function(result){
status = updateStatus(statusSpan, result); status = updateStatus(statusSpan, result);
if (callback) {
callback(status);
}
} }
}); });
}); });
@ -137,9 +143,15 @@ OC.MountConfig={
}, },
success: function(result) { success: function(result) {
status = updateStatus(statusSpan, result); status = updateStatus(statusSpan, result);
if (callback) {
callback(status);
}
}, },
error: function(result){ error: function(result){
status = updateStatus(statusSpan, result); status = updateStatus(statusSpan, result);
if (callback) {
callback(status);
}
} }
}); });
} }

View File

@ -224,7 +224,7 @@ class DAV extends \OC\Files\Storage\Common{
if (isset($response['{DAV:}quota-available-bytes'])) { if (isset($response['{DAV:}quota-available-bytes'])) {
return (int)$response['{DAV:}quota-available-bytes']; return (int)$response['{DAV:}quota-available-bytes'];
} else { } else {
return 0; return \OC\Files\SPACE_UNKNOWN;
} }
} catch(\Exception $e) { } catch(\Exception $e) {
return \OC\Files\SPACE_UNKNOWN; return \OC\Files\SPACE_UNKNOWN;

View File

@ -39,6 +39,7 @@ if(!isset($linkedItem['uid_owner']) || !isset($linkedItem['file_source'])) {
$rootLinkItem = OCP\Share::resolveReShare($linkedItem); $rootLinkItem = OCP\Share::resolveReShare($linkedItem);
$userId = $rootLinkItem['uid_owner']; $userId = $rootLinkItem['uid_owner'];
OCP\JSON::checkUserExists($rootLinkItem['uid_owner']);
\OC_Util::setupFS($userId); \OC_Util::setupFS($userId);
\OC\Files\Filesystem::initMountPoints($userId); \OC\Files\Filesystem::initMountPoints($userId);
$view = new \OC\Files\View('/' . $userId . '/files'); $view = new \OC\Files\View('/' . $userId . '/files');
@ -88,4 +89,4 @@ try{
} catch (\Exception $e) { } catch (\Exception $e) {
\OC_Response::setStatus(500); \OC_Response::setStatus(500);
\OC_Log::write('core', $e->getmessage(), \OC_Log::DEBUG); \OC_Log::write('core', $e->getmessage(), \OC_Log::DEBUG);
} }

View File

@ -44,6 +44,7 @@ if (version_compare($installedVersion, '0.3', '<')) {
$shareType = OCP\Share::SHARE_TYPE_USER; $shareType = OCP\Share::SHARE_TYPE_USER;
$shareWith = $row['uid_shared_with']; $shareWith = $row['uid_shared_with'];
} }
OCP\JSON::checkUserExists($row['uid_owner']);
OC_User::setUserId($row['uid_owner']); OC_User::setUserId($row['uid_owner']);
//we need to setup the filesystem for the user, otherwise OC_FileSystem::getRoot will fail and break //we need to setup the filesystem for the user, otherwise OC_FileSystem::getRoot will fail and break
OC_Util::setupFS($row['uid_owner']); OC_Util::setupFS($row['uid_owner']);

View File

@ -141,10 +141,13 @@ thead{
.directLink { .directLink {
margin-bottom: 20px; margin-bottom: 20px;
} }
.directLink label { .directLink label {
font-weight: normal; font-weight: normal;
} }
.directLink input { .directLink input {
margin-left: 10px; margin-left: 10px;
width: 300px; width: 300px;
} }
.public_actions {
padding: 4px;
}

View File

@ -59,7 +59,8 @@ $(document).ready(function() {
}); });
// Add Uploadprogress Wrapper to controls bar // Add Uploadprogress Wrapper to controls bar
$('#controls').append($('#additional_controls div#uploadprogresswrapper')); $('#controls').append($('#controls .actions div#uploadprogresswrapper'));
$('#uploadprogresswrapper').addClass('public_actions');
// Cancel upload trigger // Cancel upload trigger
$('#cancel_upload_button').click(function() { $('#cancel_upload_button').click(function() {

View File

@ -32,7 +32,7 @@ class Shared_Watcher extends Watcher {
* @param string $path * @param string $path
*/ */
public function checkUpdate($path) { public function checkUpdate($path) {
if ($path != '' && parent::checkUpdate($path)) { if ($path != '' && parent::checkUpdate($path) === true) {
// since checkUpdate() has already updated the size of the subdirs, // since checkUpdate() has already updated the size of the subdirs,
// only apply the update to the owner's parent dirs // only apply the update to the owner's parent dirs

View File

@ -35,7 +35,7 @@ function determineIcon($file, $sharingRoot, $sharingToken) {
if (isset($_GET['t'])) { if (isset($_GET['t'])) {
$token = $_GET['t']; $token = $_GET['t'];
$linkItem = OCP\Share::getShareByToken($token); $linkItem = OCP\Share::getShareByToken($token, false);
if (is_array($linkItem) && isset($linkItem['uid_owner'])) { if (is_array($linkItem) && isset($linkItem['uid_owner'])) {
// seems to be a valid share // seems to be a valid share
$type = $linkItem['item_type']; $type = $linkItem['item_type'];
@ -43,10 +43,10 @@ if (isset($_GET['t'])) {
$shareOwner = $linkItem['uid_owner']; $shareOwner = $linkItem['uid_owner'];
$path = null; $path = null;
$rootLinkItem = OCP\Share::resolveReShare($linkItem); $rootLinkItem = OCP\Share::resolveReShare($linkItem);
$fileOwner = $rootLinkItem['uid_owner']; if (isset($rootLinkItem['uid_owner'])) {
if (isset($fileOwner)) { OCP\JSON::checkUserExists($rootLinkItem['uid_owner']);
OC_Util::tearDownFS(); OC_Util::tearDownFS();
OC_Util::setupFS($fileOwner); OC_Util::setupFS($rootLinkItem['uid_owner']);
$path = \OC\Files\Filesystem::getPath($linkItem['file_source']); $path = \OC\Files\Filesystem::getPath($linkItem['file_source']);
} }
} }
@ -111,6 +111,7 @@ if (isset($path)) {
} }
} }
$basePath = $path; $basePath = $path;
$rootName = basename($path);
if (isset($_GET['path']) && \OC\Files\Filesystem::isReadable($basePath . $_GET['path'])) { if (isset($_GET['path']) && \OC\Files\Filesystem::isReadable($basePath . $_GET['path'])) {
$getPath = \OC\Files\Filesystem::normalizePath($_GET['path']); $getPath = \OC\Files\Filesystem::normalizePath($_GET['path']);
$path .= $getPath; $path .= $getPath;
@ -188,8 +189,8 @@ if (isset($path)) {
} else { } else {
$i['extension'] = ''; $i['extension'] = '';
} }
$i['isPreviewAvailable'] = \OC::$server->getPreviewManager()->isMimeSupported($i['mimetype']);
} }
$i['isPreviewAvailable'] = \OC::$server->getPreviewManager()->isMimeSupported($i['mimetype']);
$i['directory'] = $getPath; $i['directory'] = $getPath;
$i['permissions'] = OCP\PERMISSION_READ; $i['permissions'] = OCP\PERMISSION_READ;
$i['icon'] = determineIcon($i, $basePath, $token); $i['icon'] = determineIcon($i, $basePath, $token);
@ -216,6 +217,7 @@ if (isset($path)) {
$list->assign('sharingroot', $basePath); $list->assign('sharingroot', $basePath);
$breadcrumbNav = new OCP\Template('files', 'part.breadcrumb', ''); $breadcrumbNav = new OCP\Template('files', 'part.breadcrumb', '');
$breadcrumbNav->assign('breadcrumb', $breadcrumb); $breadcrumbNav->assign('breadcrumb', $breadcrumb);
$breadcrumbNav->assign('rootBreadCrumb', $rootName);
$breadcrumbNav->assign('baseURL', OCP\Util::linkToPublic('files') . $urlLinkIdentifiers . '&path='); $breadcrumbNav->assign('baseURL', OCP\Util::linkToPublic('files') . $urlLinkIdentifiers . '&path=');
$maxUploadFilesize=OCP\Util::maxUploadFilesize($path); $maxUploadFilesize=OCP\Util::maxUploadFilesize($path);
$fileHeader = (!isset($files) or count($files) > 0); $fileHeader = (!isset($files) or count($files) > 0);

View File

@ -24,9 +24,10 @@
<?php if (!isset($_['folder']) || $_['allowZipDownload']): ?> <?php if (!isset($_['folder']) || $_['allowZipDownload']): ?>
<a href="<?php p($_['downloadURL']); ?>" class="button" id="download"><img <a href="<?php p($_['downloadURL']); ?>" class="button" id="download">
class="svg" alt="Download" src="<?php print_unescaped(OCP\image_path("core", "actions/download.svg")); ?>" <img class="svg" alt="Download" src="<?php print_unescaped(OCP\image_path("core", "actions/download.svg")); ?>" />
/><span><?php p($l->t('Download'))?></span></a> <span><?php p($l->t('Download'))?></span>
</a>
<?php endif; ?> <?php endif; ?>
<?php if ($_['allowPublicUploadEnabled']):?> <?php if ($_['allowPublicUploadEnabled']):?>
@ -43,28 +44,17 @@
<?php endif;?> <?php endif;?>
<div id="data-upload-form" class="button" title="<?php p($l->t('Upload') . ' max. '.$_['uploadMaxHumanFilesize']) ?>"> <div id="data-upload-form" title="<?php p($l->t('Upload') . ' max. '.$_['uploadMaxHumanFilesize']) ?>">
<input id="file_upload_start" type="file" name="files[]" data-url="<?php print_unescaped(OCP\Util::linkTo('files', 'ajax/upload.php')); ?>" multiple> <input id="file_upload_start" type="file" name="files[]" data-url="<?php print_unescaped(OCP\Util::linkTo('files', 'ajax/upload.php')); ?>" multiple>
<a href="#" id="publicUploadButtonMock" class="svg"> <a href="#" id="public_upload" class="button">
<img class="svg" alt="Upload" src="<?php print_unescaped(OCP\image_path("core", "actions/upload.svg")); ?>" />
<span><?php p($l->t('Upload'))?></span> <span><?php p($l->t('Upload'))?></span>
</a> </a>
</div> </div>
</div> </div>
<div>
<div id="additional_controls" style="display:none">
<div id="uploadprogresswrapper">
<div id="uploadprogressbar"></div>
<input id="cancel_upload_button" type="button" class="stop" style="display:none"
value="<?php p($l->t('Cancel upload'));?>"
/>
</div>
<?php endif; ?> <?php endif; ?>
</div> </div>
</div></header> </div></header>
<div id="content"> <div id="content">

View File

@ -189,7 +189,7 @@ class Trashbin {
if ($rootView->is_dir($owner . '/files_versions/' . $ownerPath)) { if ($rootView->is_dir($owner . '/files_versions/' . $ownerPath)) {
$size += self::calculateSize(new \OC\Files\View('/' . $owner . '/files_versions/' . $ownerPath)); $size += self::calculateSize(new \OC\Files\View('/' . $owner . '/files_versions/' . $ownerPath));
if ($owner !== $user) { if ($owner !== $user) {
$rootView->copy($owner . '/files_versions/' . $ownerPath, $owner . '/files_trashbin/versions/' . basename($ownerPath) . '.d' . $timestamp); self::copy_recursive($owner . '/files_versions/' . $ownerPath, $owner . '/files_trashbin/versions/' . basename($ownerPath) . '.d' . $timestamp, $rootView);
} }
$rootView->rename($owner . '/files_versions/' . $ownerPath, $user . '/files_trashbin/versions/' . $filename . '.d' . $timestamp); $rootView->rename($owner . '/files_versions/' . $ownerPath, $user . '/files_trashbin/versions/' . $filename . '.d' . $timestamp);
} else if ($versions = \OCA\Files_Versions\Storage::getVersions($owner, $ownerPath)) { } else if ($versions = \OCA\Files_Versions\Storage::getVersions($owner, $ownerPath)) {
@ -247,7 +247,7 @@ class Trashbin {
if ($rootView->is_dir($keyfile)) { if ($rootView->is_dir($keyfile)) {
$size += self::calculateSize(new \OC\Files\View($keyfile)); $size += self::calculateSize(new \OC\Files\View($keyfile));
if ($owner !== $user) { if ($owner !== $user) {
$rootView->copy($keyfile, $owner . '/files_trashbin/keyfiles/' . basename($ownerPath) . '.d' . $timestamp); self::copy_recursive($keyfile, $owner . '/files_trashbin/keyfiles/' . basename($ownerPath) . '.d' . $timestamp, $rootView);
} }
$rootView->rename($keyfile, $user . '/files_trashbin/keyfiles/' . $filename . '.d' . $timestamp); $rootView->rename($keyfile, $user . '/files_trashbin/keyfiles/' . $filename . '.d' . $timestamp);
} else { } else {
@ -265,7 +265,7 @@ class Trashbin {
if ($rootView->is_dir($sharekeys)) { if ($rootView->is_dir($sharekeys)) {
$size += self::calculateSize(new \OC\Files\View($sharekeys)); $size += self::calculateSize(new \OC\Files\View($sharekeys));
if ($owner !== $user) { if ($owner !== $user) {
$rootView->copy($sharekeys, $owner . '/files_trashbin/share-keys/' . basename($ownerPath) . '.d' . $timestamp); self::copy_recursive($sharekeys, $owner . '/files_trashbin/share-keys/' . basename($ownerPath) . '.d' . $timestamp, $rootView);
} }
$rootView->rename($sharekeys, $user . '/files_trashbin/share-keys/' . $filename . '.d' . $timestamp); $rootView->rename($sharekeys, $user . '/files_trashbin/share-keys/' . $filename . '.d' . $timestamp);
} else { } else {
@ -734,7 +734,7 @@ class Trashbin {
// calculate available space for trash bin // calculate available space for trash bin
// subtract size of files and current trash bin size from quota // subtract size of files and current trash bin size from quota
if ($softQuota) { if ($softQuota) {
$rootInfo = $view->getFileInfo('/files/'); $rootInfo = $view->getFileInfo('/files/', false);
$free = $quota - $rootInfo['size']; // remaining free space for user $free = $quota - $rootInfo['size']; // remaining free space for user
if ($free > 0) { if ($free > 0) {
$availableSpace = ($free * self::DEFAULTMAXSIZE / 100) - $trashbinSize; // how much space can be used for versions $availableSpace = ($free * self::DEFAULTMAXSIZE / 100) - $trashbinSize; // how much space can be used for versions

View File

@ -5,7 +5,8 @@ $source = $_GET['source'];
$start = $_GET['start']; $start = $_GET['start'];
list ($uid, $filename) = OCA\Files_Versions\Storage::getUidAndFilename($source); list ($uid, $filename) = OCA\Files_Versions\Storage::getUidAndFilename($source);
$count = 5; //show the newest revisions $count = 5; //show the newest revisions
if( ($versions = OCA\Files_Versions\Storage::getVersions($uid, $filename)) ) { $versions = OCA\Files_Versions\Storage::getVersions($uid, $filename, $source);
if( $versions ) {
$endReached = false; $endReached = false;
if (count($versions) <= $start+$count) { if (count($versions) <= $start+$count) {

View File

@ -12,18 +12,11 @@ if(!\OC_App::isEnabled('files_versions')){
} }
$file = array_key_exists('file', $_GET) ? (string) urldecode($_GET['file']) : ''; $file = array_key_exists('file', $_GET) ? (string) urldecode($_GET['file']) : '';
$user = array_key_exists('user', $_GET) ? $_GET['user'] : '';
$maxX = array_key_exists('x', $_GET) ? (int) $_GET['x'] : 44; $maxX = array_key_exists('x', $_GET) ? (int) $_GET['x'] : 44;
$maxY = array_key_exists('y', $_GET) ? (int) $_GET['y'] : 44; $maxY = array_key_exists('y', $_GET) ? (int) $_GET['y'] : 44;
$version = array_key_exists('version', $_GET) ? $_GET['version'] : ''; $version = array_key_exists('version', $_GET) ? $_GET['version'] : '';
$scalingUp = array_key_exists('scalingup', $_GET) ? (bool) $_GET['scalingup'] : true; $scalingUp = array_key_exists('scalingup', $_GET) ? (bool) $_GET['scalingup'] : true;
if($user === '') {
\OC_Response::setStatus(400); //400 Bad Request
\OC_Log::write('versions-preview', 'No user parameter was passed', \OC_Log::DEBUG);
exit;
}
if($file === '' && $version === '') { if($file === '' && $version === '') {
\OC_Response::setStatus(400); //400 Bad Request \OC_Response::setStatus(400); //400 Bad Request
\OC_Log::write('versions-preview', 'No file parameter was passed', \OC_Log::DEBUG); \OC_Log::write('versions-preview', 'No file parameter was passed', \OC_Log::DEBUG);
@ -36,7 +29,8 @@ if($maxX === 0 || $maxY === 0) {
exit; exit;
} }
try{ try {
list($user, $file) = \OCA\Files_Versions\Storage::getUidAndFilename($file);
$preview = new \OC\Preview($user, 'files_versions', $file.'.v'.$version); $preview = new \OC\Preview($user, 'files_versions', $file.'.v'.$version);
$mimetype = \OC_Helper::getFileNameMimeType($file); $mimetype = \OC_Helper::getFileNameMimeType($file);
$preview->setMimetype($mimetype); $preview->setMimetype($mimetype);

View File

@ -261,11 +261,12 @@ class Storage {
/** /**
* @brief get a list of all available versions of a file in descending chronological order * @brief get a list of all available versions of a file in descending chronological order
* @param $uid user id from the owner of the file * @param string $uid user id from the owner of the file
* @param $filename file to find versions of, relative to the user files dir * @param string $filename file to find versions of, relative to the user files dir
* @returns array * @param string $userFullPath
* @returns array versions newest version first
*/ */
public static function getVersions($uid, $filename) { public static function getVersions($uid, $filename, $userFullPath = '') {
$versions = array(); $versions = array();
// fetch for old versions // fetch for old versions
$view = new \OC\Files\View('/' . $uid . '/' . self::VERSIONS_ROOT); $view = new \OC\Files\View('/' . $uid . '/' . self::VERSIONS_ROOT);
@ -286,7 +287,11 @@ class Storage {
$versions[$key]['cur'] = 0; $versions[$key]['cur'] = 0;
$versions[$key]['version'] = $version; $versions[$key]['version'] = $version;
$versions[$key]['humanReadableTimestamp'] = self::getHumanReadableTimestamp($version); $versions[$key]['humanReadableTimestamp'] = self::getHumanReadableTimestamp($version);
$versions[$key]['preview'] = \OCP\Util::linkToRoute('core_ajax_versions_preview', array('file' => $filename, 'version' => $version, 'user' => $uid)); if (empty($userFullPath)) {
$versions[$key]['preview'] = '';
} else {
$versions[$key]['preview'] = \OCP\Util::linkToRoute('core_ajax_versions_preview', array('file' => $userFullPath, 'version' => $version));
}
$versions[$key]['path'] = $filename; $versions[$key]['path'] = $filename;
$versions[$key]['name'] = $versionedFile; $versions[$key]['name'] = $versionedFile;
$versions[$key]['size'] = $file['size']; $versions[$key]['size'] = $file['size'];
@ -392,12 +397,13 @@ class Storage {
} }
} }
ksort($versions); // newest version first
krsort($versions);
$result = array(); $result = array();
foreach ($versions as $key => $value) { foreach ($versions as $key => $value) {
$size = $view->filesize($value['path']); $size = $view->filesize(self::VERSIONS_ROOT.'/'.$value['path'].'.v'.$value['timestamp']);
$filename = $value['path']; $filename = $value['path'];
$result['all'][$key]['version'] = $value['timestamp']; $result['all'][$key]['version'] = $value['timestamp'];
@ -412,6 +418,63 @@ class Storage {
return $result; return $result;
} }
/**
* @brief get list of files we want to expire
* @param int $currentTime timestamp of current time
* @param array $versions list of versions
* @return array containing the list of to deleted versions and the size of them
*/
protected static function getExpireList($time, $versions) {
$size = 0;
$toDelete = array(); // versions we want to delete
$interval = 1;
$step = Storage::$max_versions_per_interval[$interval]['step'];
if (Storage::$max_versions_per_interval[$interval]['intervalEndsAfter'] == -1) {
$nextInterval = -1;
} else {
$nextInterval = $time - Storage::$max_versions_per_interval[$interval]['intervalEndsAfter'];
}
$firstVersion = reset($versions);
$firstKey = key($versions);
$prevTimestamp = $firstVersion['version'];
$nextVersion = $firstVersion['version'] - $step;
unset($versions[$firstKey]);
foreach ($versions as $key => $version) {
$newInterval = true;
while ($newInterval) {
if ($nextInterval == -1 || $prevTimestamp > $nextInterval) {
if ($version['version'] > $nextVersion) {
//distance between two version too small, mark to delete
$toDelete[$key] = $version['path'] . '.v' . $version['version'];
$size += $version['size'];
\OCP\Util::writeLog('files_versions', 'Mark to expire '. $version['path'] .' next version should be ' . $nextVersion . " or smaller. (prevTimestamp: " . $prevTimestamp . "; step: " . $step, \OCP\Util::DEBUG);
} else {
$nextVersion = $version['version'] - $step;
$prevTimestamp = $version['version'];
}
$newInterval = false; // version checked so we can move to the next one
} else { // time to move on to the next interval
$interval++;
$step = Storage::$max_versions_per_interval[$interval]['step'];
$nextVersion = $prevTimestamp - $step;
if (Storage::$max_versions_per_interval[$interval]['intervalEndsAfter'] == -1) {
$nextInterval = -1;
} else {
$nextInterval = $time - Storage::$max_versions_per_interval[$interval]['intervalEndsAfter'];
}
$newInterval = true; // we changed the interval -> check same version with new interval
}
}
}
return array($toDelete, $size);
}
/** /**
* @brief Erase a file's versions which exceed the set quota * @brief Erase a file's versions which exceed the set quota
*/ */
@ -445,7 +508,7 @@ class Storage {
// subtract size of files and current versions size from quota // subtract size of files and current versions size from quota
if ($softQuota) { if ($softQuota) {
$files_view = new \OC\Files\View('/'.$uid.'/files'); $files_view = new \OC\Files\View('/'.$uid.'/files');
$rootInfo = $files_view->getFileInfo('/'); $rootInfo = $files_view->getFileInfo('/', false);
$free = $quota-$rootInfo['size']; // remaining free space for user $free = $quota-$rootInfo['size']; // remaining free space for user
if ( $free > 0 ) { if ( $free > 0 ) {
$availableSpace = ($free * self::DEFAULTMAXSIZE / 100) - ($versionsSize + $offset); // how much space can be used for versions $availableSpace = ($free * self::DEFAULTMAXSIZE / 100) - ($versionsSize + $offset); // how much space can be used for versions
@ -456,33 +519,35 @@ class Storage {
$availableSpace = $quota - $offset; $availableSpace = $quota - $offset;
} }
// with the probability of 0.1% we reduce the number of all versions not only for the current file
$random = rand(0, 1000);
if ($random == 0) {
$allFiles = true;
} else {
$allFiles = false;
}
$allVersions = Storage::getVersions($uid, $filename); $allVersions = Storage::getVersions($uid, $filename);
$versionsByFile[$filename] = $allVersions;
$sizeOfDeletedVersions = self::delOldVersions($versionsByFile, $allVersions, $versionsFileview); $time = time();
list($toDelete, $sizeOfDeletedVersions) = self::getExpireList($time, $allVersions);
$availableSpace = $availableSpace + $sizeOfDeletedVersions; $availableSpace = $availableSpace + $sizeOfDeletedVersions;
$versionsSize = $versionsSize - $sizeOfDeletedVersions; $versionsSize = $versionsSize - $sizeOfDeletedVersions;
// if still not enough free space we rearrange the versions from all files // if still not enough free space we rearrange the versions from all files
if ($availableSpace <= 0 || $allFiles) { if ($availableSpace <= 0) {
$result = Storage::getAllVersions($uid); $result = Storage::getAllVersions($uid);
$versionsByFile = $result['by_file'];
$allVersions = $result['all']; $allVersions = $result['all'];
$sizeOfDeletedVersions = self::delOldVersions($versionsByFile, $allVersions, $versionsFileview); foreach ($result['by_file'] as $versions) {
list($toDeleteNew, $size) = self::getExpireList($time, $versions);
$toDelete = array_merge($toDelete, $toDeleteNew);
$sizeOfDeletedVersions += $size;
}
$availableSpace = $availableSpace + $sizeOfDeletedVersions; $availableSpace = $availableSpace + $sizeOfDeletedVersions;
$versionsSize = $versionsSize - $sizeOfDeletedVersions; $versionsSize = $versionsSize - $sizeOfDeletedVersions;
} }
foreach($toDelete as $key => $path) {
\OC_Hook::emit('\OCP\Versions', 'delete', array('path' => $path));
$versionsFileview->unlink($path);
unset($allVersions[$key]); // update array with the versions we keep
\OCP\Util::writeLog('files_versions', "Expire: " . $path, \OCP\Util::DEBUG);
}
// Check if enough space is available after versions are rearranged. // Check if enough space is available after versions are rearranged.
// If not we delete the oldest versions until we meet the size limit for versions, // If not we delete the oldest versions until we meet the size limit for versions,
// but always keep the two latest versions // but always keep the two latest versions
@ -492,6 +557,7 @@ class Storage {
$version = current($allVersions); $version = current($allVersions);
$versionsFileview->unlink($version['path'].'.v'.$version['version']); $versionsFileview->unlink($version['path'].'.v'.$version['version']);
\OC_Hook::emit('\OCP\Versions', 'delete', array('path' => $version['path'].'.v'.$version['version'])); \OC_Hook::emit('\OCP\Versions', 'delete', array('path' => $version['path'].'.v'.$version['version']));
\OCP\Util::writeLog('files_versions', 'running out of space! Delete oldest version: ' . $version['path'].'.v'.$version['version'] , \OCP\Util::DEBUG);
$versionsSize -= $version['size']; $versionsSize -= $version['size'];
$availableSpace += $version['size']; $availableSpace += $version['size'];
next($allVersions); next($allVersions);
@ -504,69 +570,6 @@ class Storage {
return false; return false;
} }
/**
* @brief delete old version from a given list of versions
*
* @param array $versionsByFile list of versions ordered by files
* @param array $allVversions all versions accross multiple files
* @param $versionsFileview OC\Files\View on data/user/files_versions
* @return size of releted versions
*/
private static function delOldVersions($versionsByFile, &$allVersions, $versionsFileview) {
$time = time();
$size = 0;
// delete old versions for every given file
foreach ($versionsByFile as $versions) {
$versions = array_reverse($versions); // newest version first
$interval = 1;
$step = Storage::$max_versions_per_interval[$interval]['step'];
if (Storage::$max_versions_per_interval[$interval]['intervalEndsAfter'] == -1) {
$nextInterval = -1;
} else {
$nextInterval = $time - Storage::$max_versions_per_interval[$interval]['intervalEndsAfter'];
}
$firstVersion = reset($versions);
$firstKey = key($versions);
$prevTimestamp = $firstVersion['version'];
$nextVersion = $firstVersion['version'] - $step;
unset($versions[$firstKey]);
foreach ($versions as $key => $version) {
$newInterval = true;
while ($newInterval) {
if ($nextInterval == -1 || $version['version'] >= $nextInterval) {
if ($version['version'] > $nextVersion) {
//distance between two version too small, delete version
$versionsFileview->unlink($version['path'] . '.v' . $version['version']);
\OC_Hook::emit('\OCP\Versions', 'delete', array('path' => $version['path'] . '.v' . $version['version']));
$size += $version['size'];
unset($allVersions[$key]); // update array with all versions
} else {
$nextVersion = $version['version'] - $step;
}
$newInterval = false; // version checked so we can move to the next one
} else { // time to move on to the next interval
$interval++;
$step = Storage::$max_versions_per_interval[$interval]['step'];
$nextVersion = $prevTimestamp - $step;
if (Storage::$max_versions_per_interval[$interval]['intervalEndsAfter'] == -1) {
$nextInterval = -1;
} else {
$nextInterval = $time - Storage::$max_versions_per_interval[$interval]['intervalEndsAfter'];
}
$newInterval = true; // we changed the interval -> check same version with new interval
}
}
$prevTimestamp = $version['version'];
}
}
return $size;
}
/** /**
* @brief create recursively missing directories * @brief create recursively missing directories
* @param string $filename $path to a file * @param string $filename $path to a file

View File

@ -0,0 +1,188 @@
<?php
/**
* ownCloud
*
* @author Bjoern Schiessle
* @copyright 2014 Bjoern Schiessle <schiessle@owncloud.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
* License as published by the Free Software Foundation; either
* version 3 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
*
* You should have received a copy of the GNU Affero General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
*/
require_once __DIR__ . '/../lib/versions.php';
/**
* Class Test_Files_versions
* @brief this class provide basic files versions test
*/
class Test_Files_Versioning extends \PHPUnit_Framework_TestCase {
/**
* @medium
* @brief test expire logic
* @dataProvider versionsProvider
*/
function testGetExpireList($versions, $sizeOfAllDeletedFiles) {
// last interval enda at 2592000
$startTime = 5000000;
$testClass = new VersionStorageToTest();
list($deleted, $size) = $testClass->callProtectedGetExpireList($startTime, $versions);
// we should have deleted 16 files each of the size 1
$this->assertEquals($sizeOfAllDeletedFiles, $size);
// the deleted array should only contain versions which should be deleted
foreach($deleted as $key => $path) {
unset($versions[$key]);
$this->assertEquals("delete", substr($path, 0, strlen("delete")));
}
// the versions array should only contain versions which should be kept
foreach ($versions as $version) {
$this->assertEquals("keep", $version['path']);
}
}
public function versionsProvider() {
return array(
// first set of versions uniformly distributed versions
array(
array(
// first slice (10sec) keep one version every 2 seconds
array("version" => 4999999, "path" => "keep", "size" => 1),
array("version" => 4999998, "path" => "delete", "size" => 1),
array("version" => 4999997, "path" => "keep", "size" => 1),
array("version" => 4999995, "path" => "keep", "size" => 1),
array("version" => 4999994, "path" => "delete", "size" => 1),
//next slice (60sec) starts at 4999990 keep one version every 10 secons
array("version" => 4999988, "path" => "keep", "size" => 1),
array("version" => 4999978, "path" => "keep", "size" => 1),
array("version" => 4999975, "path" => "delete", "size" => 1),
array("version" => 4999972, "path" => "delete", "size" => 1),
array("version" => 4999967, "path" => "keep", "size" => 1),
array("version" => 4999958, "path" => "delete", "size" => 1),
array("version" => 4999957, "path" => "keep", "size" => 1),
//next slice (3600sec) start at 4999940 keep one version every 60 seconds
array("version" => 4999900, "path" => "keep", "size" => 1),
array("version" => 4999841, "path" => "delete", "size" => 1),
array("version" => 4999840, "path" => "keep", "size" => 1),
array("version" => 4999780, "path" => "keep", "size" => 1),
array("version" => 4996401, "path" => "keep", "size" => 1),
// next slice (86400sec) start at 4996400 keep one version every 3600 seconds
array("version" => 4996350, "path" => "delete", "size" => 1),
array("version" => 4992800, "path" => "keep", "size" => 1),
array("version" => 4989800, "path" => "delete", "size" => 1),
array("version" => 4989700, "path" => "delete", "size" => 1),
array("version" => 4989200, "path" => "keep", "size" => 1),
// next slice (2592000sec) start at 4913600 keep one version every 86400 seconds
array("version" => 4913600, "path" => "keep", "size" => 1),
array("version" => 4852800, "path" => "delete", "size" => 1),
array("version" => 4827201, "path" => "delete", "size" => 1),
array("version" => 4827200, "path" => "keep", "size" => 1),
array("version" => 4777201, "path" => "delete", "size" => 1),
array("version" => 4777501, "path" => "delete", "size" => 1),
array("version" => 4740000, "path" => "keep", "size" => 1),
// final slice starts at 2408000 keep one version every 604800 secons
array("version" => 2408000, "path" => "keep", "size" => 1),
array("version" => 1803201, "path" => "delete", "size" => 1),
array("version" => 1803200, "path" => "keep", "size" => 1),
array("version" => 1800199, "path" => "delete", "size" => 1),
array("version" => 1800100, "path" => "delete", "size" => 1),
array("version" => 1198300, "path" => "keep", "size" => 1),
),
16 // size of all deleted files (every file has the size 1)
),
// second set of versions, here we have only really old versions
array(
array(
// first slice (10sec) keep one version every 2 seconds
// next slice (60sec) starts at 4999990 keep one version every 10 secons
// next slice (3600sec) start at 4999940 keep one version every 60 seconds
// next slice (86400sec) start at 4996400 keep one version every 3600 seconds
array("version" => 4996400, "path" => "keep", "size" => 1),
array("version" => 4996350, "path" => "delete", "size" => 1),
array("version" => 4996350, "path" => "delete", "size" => 1),
array("version" => 4992800, "path" => "keep", "size" => 1),
array("version" => 4989800, "path" => "delete", "size" => 1),
array("version" => 4989700, "path" => "delete", "size" => 1),
array("version" => 4989200, "path" => "keep", "size" => 1),
// next slice (2592000sec) start at 4913600 keep one version every 86400 seconds
array("version" => 4913600, "path" => "keep", "size" => 1),
array("version" => 4852800, "path" => "delete", "size" => 1),
array("version" => 4827201, "path" => "delete", "size" => 1),
array("version" => 4827200, "path" => "keep", "size" => 1),
array("version" => 4777201, "path" => "delete", "size" => 1),
array("version" => 4777501, "path" => "delete", "size" => 1),
array("version" => 4740000, "path" => "keep", "size" => 1),
// final slice starts at 2408000 keep one version every 604800 secons
array("version" => 2408000, "path" => "keep", "size" => 1),
array("version" => 1803201, "path" => "delete", "size" => 1),
array("version" => 1803200, "path" => "keep", "size" => 1),
array("version" => 1800199, "path" => "delete", "size" => 1),
array("version" => 1800100, "path" => "delete", "size" => 1),
array("version" => 1198300, "path" => "keep", "size" => 1),
),
11 // size of all deleted files (every file has the size 1)
),
// third set of versions, with some gaps inbetween
array(
array(
// first slice (10sec) keep one version every 2 seconds
array("version" => 4999999, "path" => "keep", "size" => 1),
array("version" => 4999998, "path" => "delete", "size" => 1),
array("version" => 4999997, "path" => "keep", "size" => 1),
array("version" => 4999995, "path" => "keep", "size" => 1),
array("version" => 4999994, "path" => "delete", "size" => 1),
//next slice (60sec) starts at 4999990 keep one version every 10 secons
array("version" => 4999988, "path" => "keep", "size" => 1),
array("version" => 4999978, "path" => "keep", "size" => 1),
//next slice (3600sec) start at 4999940 keep one version every 60 seconds
// next slice (86400sec) start at 4996400 keep one version every 3600 seconds
array("version" => 4989200, "path" => "keep", "size" => 1),
// next slice (2592000sec) start at 4913600 keep one version every 86400 seconds
array("version" => 4913600, "path" => "keep", "size" => 1),
array("version" => 4852800, "path" => "delete", "size" => 1),
array("version" => 4827201, "path" => "delete", "size" => 1),
array("version" => 4827200, "path" => "keep", "size" => 1),
array("version" => 4777201, "path" => "delete", "size" => 1),
array("version" => 4777501, "path" => "delete", "size" => 1),
array("version" => 4740000, "path" => "keep", "size" => 1),
// final slice starts at 2408000 keep one version every 604800 secons
array("version" => 2408000, "path" => "keep", "size" => 1),
array("version" => 1803201, "path" => "delete", "size" => 1),
array("version" => 1803200, "path" => "keep", "size" => 1),
array("version" => 1800199, "path" => "delete", "size" => 1),
array("version" => 1800100, "path" => "delete", "size" => 1),
array("version" => 1198300, "path" => "keep", "size" => 1),
),
9 // size of all deleted files (every file has the size 1)
),
);
}
}
// extend the original class to make it possible to test protected methods
class VersionStorageToTest extends \OCA\Files_Versions\Storage {
public function callProtectedGetExpireList($time, $versions) {
return self::getExpireList($time, $versions);
}
}

View File

@ -48,18 +48,25 @@ class Helper {
static public function getServerConfigurationPrefixes($activeConfigurations = false) { static public function getServerConfigurationPrefixes($activeConfigurations = false) {
$referenceConfigkey = 'ldap_configuration_active'; $referenceConfigkey = 'ldap_configuration_active';
$query = ' $sql = '
SELECT DISTINCT `configkey` SELECT DISTINCT `configkey`
FROM `*PREFIX*appconfig` FROM `*PREFIX*appconfig`
WHERE `appid` = \'user_ldap\' WHERE `appid` = \'user_ldap\'
AND `configkey` LIKE ? AND `configkey` LIKE ?
'; ';
if($activeConfigurations) {
$query .= ' AND `configvalue` = \'1\'';
}
$query = \OCP\DB::prepare($query);
$serverConfigs = $query->execute(array('%'.$referenceConfigkey))->fetchAll(); if($activeConfigurations) {
if (\OC_Config::getValue( 'dbtype', 'sqlite' ) === 'oci') {
//FIXME oracle hack: need to explicitly cast CLOB to CHAR for comparison
$sql .= ' AND to_char(`configvalue`)=\'1\'';
} else {
$sql .= ' AND `configvalue` = \'1\'';
}
}
$stmt = \OCP\DB::prepare($sql);
$serverConfigs = $stmt->execute(array('%'.$referenceConfigkey))->fetchAll();
$prefixes = array(); $prefixes = array();
foreach($serverConfigs as $serverConfig) { foreach($serverConfigs as $serverConfig) {

View File

@ -416,6 +416,9 @@ var OC={
throw e; throw e;
}); });
} }
if(!SVGSupport()) {
replaceSVG();
}
}).show(); }).show();
}, 'html'); }, 'html');
} }

View File

@ -57,6 +57,9 @@ class OC {
* web path in 'url' * web path in 'url'
*/ */
public static $APPSROOTS = array(); public static $APPSROOTS = array();
public static $configDir;
/* /*
* requested app * requested app
*/ */
@ -100,6 +103,13 @@ class OC {
get_include_path() get_include_path()
); );
if(defined('PHPUNIT_RUN') and PHPUNIT_RUN and is_dir(OC::$SERVERROOT . '/tests/config/')) {
self::$configDir = OC::$SERVERROOT . '/tests/config/';
} else {
self::$configDir = OC::$SERVERROOT . '/config/';
}
OC_Config::$object = new \OC\Config(self::$configDir);
OC::$SUBURI = str_replace("\\", "/", substr(realpath($_SERVER["SCRIPT_FILENAME"]), strlen(OC::$SERVERROOT))); OC::$SUBURI = str_replace("\\", "/", substr(realpath($_SERVER["SCRIPT_FILENAME"]), strlen(OC::$SERVERROOT)));
$scriptName = OC_Request::scriptName(); $scriptName = OC_Request::scriptName();
if (substr($scriptName, -1) == '/') { if (substr($scriptName, -1) == '/') {
@ -175,8 +185,8 @@ class OC {
} }
public static function checkConfig() { public static function checkConfig() {
if (file_exists(OC::$SERVERROOT . "/config/config.php") if (file_exists(self::$configDir . "/config.php")
and !is_writable(OC::$SERVERROOT . "/config/config.php") and !is_writable(self::$configDir . "/config.php")
) { ) {
$defaults = new OC_Defaults(); $defaults = new OC_Defaults();
if (self::$CLI) { if (self::$CLI) {

View File

@ -555,6 +555,10 @@ class OC_App{
}elseif($child->getName()=='description') { }elseif($child->getName()=='description') {
$xml=(string)$child->asXML(); $xml=(string)$child->asXML();
$data[$child->getName()]=substr($xml, 13, -14);//script <description> tags $data[$child->getName()]=substr($xml, 13, -14);//script <description> tags
}elseif($child->getName()=='documentation') {
foreach($child as $subchild) {
$data["documentation"][$subchild->getName()] = (string)$subchild;
}
}else{ }else{
$data[$child->getName()]=(string)$child; $data[$child->getName()]=(string)$child;
} }

View File

@ -50,7 +50,7 @@ class Config {
protected $debugMode; protected $debugMode;
/** /**
* @param $configDir path to the config dir, needs to end with '/' * @param string $configDir path to the config dir, needs to end with '/'
*/ */
public function __construct($configDir) { public function __construct($configDir) {
$this->configDir = $configDir; $this->configDir = $configDir;

View File

@ -83,7 +83,7 @@ class OC_Files {
if ($basename) { if ($basename) {
$name = $basename . '.zip'; $name = $basename . '.zip';
} else { } else {
$name = 'owncloud.zip'; $name = 'download.zip';
} }
set_time_limit($executionTime); set_time_limit($executionTime);

View File

@ -40,7 +40,7 @@ class Watcher {
* check $path for updates * check $path for updates
* *
* @param string $path * @param string $path
* @return boolean true if path was updated, false otherwise * @return boolean | array true if path was updated, otherwise the cached data is returned
*/ */
public function checkUpdate($path) { public function checkUpdate($path) {
$cachedEntry = $this->cache->get($path); $cachedEntry = $this->cache->get($path);
@ -56,7 +56,7 @@ class Watcher {
$this->cache->correctFolderSize($path); $this->cache->correctFolderSize($path);
return true; return true;
} }
return false; return $cachedEntry;
} }
/** /**

View File

@ -95,7 +95,7 @@ class Quota extends Wrapper {
public function fopen($path, $mode) { public function fopen($path, $mode) {
$source = $this->storage->fopen($path, $mode); $source = $this->storage->fopen($path, $mode);
$free = $this->free_space(''); $free = $this->free_space('');
if ($free >= 0 && $mode !== 'r') { if ($source && $free >= 0 && $mode !== 'r' && $mode !== 'rb') {
return \OC\Files\Stream\Quota::wrap($source, $free); return \OC\Files\Stream\Quota::wrap($source, $free);
} else { } else {
return $source; return $source;

View File

@ -801,6 +801,7 @@ class View {
* @var string $internalPath * @var string $internalPath
*/ */
list($storage, $internalPath) = Filesystem::resolvePath($path); list($storage, $internalPath) = Filesystem::resolvePath($path);
$data = null;
if ($storage) { if ($storage) {
$cache = $storage->getCache($internalPath); $cache = $storage->getCache($internalPath);
$permissionsCache = $storage->getPermissionsCache($internalPath); $permissionsCache = $storage->getPermissionsCache($internalPath);
@ -811,10 +812,12 @@ class View {
$scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW); $scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW);
} else { } else {
$watcher = $storage->getWatcher($internalPath); $watcher = $storage->getWatcher($internalPath);
$watcher->checkUpdate($internalPath); $data = $watcher->checkUpdate($internalPath);
} }
$data = $cache->get($internalPath); if (!is_array($data)) {
$data = $cache->get($internalPath);
}
if ($data and $data['fileid']) { if ($data and $data['fileid']) {
if ($includeMountPoints and $data['mimetype'] === 'httpd/unix-directory') { if ($includeMountPoints and $data['mimetype'] === 'httpd/unix-directory') {

View File

@ -407,6 +407,9 @@ class OC_Installer{
include OC_App::getAppPath($app)."/appinfo/install.php"; include OC_App::getAppPath($app)."/appinfo/install.php";
} }
$info=OC_App::getAppInfo($app); $info=OC_App::getAppInfo($app);
if (is_null($info)) {
return false;
}
OC_Appconfig::setValue($app, 'installed_version', OC_App::getAppVersion($app)); OC_Appconfig::setValue($app, 'installed_version', OC_App::getAppVersion($app));
//set remote/public handelers //set remote/public handelers

View File

@ -64,6 +64,20 @@ class OC_JSON{
} }
} }
/**
* Check is a given user exists - send json error msg if not
* @param string $user
*/
public static function checkUserExists($user) {
if (!OCP\User::userExists($user)) {
$l = OC_L10N::get('lib');
OCP\JSON::error(array('data' => array('message' => $l->t('Unknown user'))));
exit;
}
}
/** /**
* Check if the user is a subadmin, send json error msg if not * Check if the user is a subadmin, send json error msg if not
*/ */

View File

@ -38,7 +38,6 @@
* This class is responsible for reading and writing config.php, the very basic * This class is responsible for reading and writing config.php, the very basic
* configuration file of ownCloud. * configuration file of ownCloud.
*/ */
OC_Config::$object = new \OC\Config(OC::$SERVERROOT.'/config/');
class OC_Config { class OC_Config {
/** /**

View File

@ -22,7 +22,7 @@ class CSSResourceLocator extends ResourceLocator {
$app = substr($style, 0, strpos($style, '/')); $app = substr($style, 0, strpos($style, '/'));
$style = substr($style, strpos($style, '/')+1); $style = substr($style, strpos($style, '/')+1);
$app_path = \OC_App::getAppPath($app); $app_path = \OC_App::getAppPath($app);
$app_url = \OC_App::getAppWebPath($app); $app_url = $this->webroot . '/index.php/apps/' . $app;
if ($this->appendIfExist($app_path, $style.$this->form_factor.'.css', $app_url) if ($this->appendIfExist($app_path, $style.$this->form_factor.'.css', $app_url)
|| $this->appendIfExist($app_path, $style.'.css', $app_url) || $this->appendIfExist($app_path, $style.'.css', $app_url)
) { ) {

View File

@ -51,6 +51,10 @@ class OC_Util {
self::$rootMounted = true; self::$rootMounted = true;
} }
if ($user != '' && !OCP\User::userExists($user)) {
return false;
}
//if we aren't logged in, there is no use to set up the filesystem //if we aren't logged in, there is no use to set up the filesystem
if( $user != "" ) { if( $user != "" ) {
\OC\Files\Filesystem::addStorageWrapper(function($mountPoint, $storage){ \OC\Files\Filesystem::addStorageWrapper(function($mountPoint, $storage){
@ -312,7 +316,7 @@ class OC_Util {
.'" target="_blank">giving the webserver write access to the root directory</a>.'; .'" target="_blank">giving the webserver write access to the root directory</a>.';
// Check if config folder is writable. // Check if config folder is writable.
if(!is_writable(OC::$SERVERROOT."/config/") or !is_readable(OC::$SERVERROOT."/config/")) { if(!is_writable(OC::$configDir) or !is_readable(OC::$configDir)) {
$errors[] = array( $errors[] = array(
'error' => "Can't write into config directory", 'error' => "Can't write into config directory",
'hint' => 'This can usually be fixed by ' 'hint' => 'This can usually be fixed by '
@ -892,6 +896,11 @@ class OC_Util {
return false; return false;
} }
// in case the connection is via proxy return true to avoid connecting to owncloud.org
if(OC_Config::getValue('proxy', '') != '') {
return true;
}
// try to connect to owncloud.org to see if http connections to the internet are possible. // try to connect to owncloud.org to see if http connections to the internet are possible.
$connected = @fsockopen("www.owncloud.org", 80); $connected = @fsockopen("www.owncloud.org", 80);
if ($connected) { if ($connected) {

View File

@ -167,7 +167,7 @@ class JSON {
* @return string json formatted string if not admin user. * @return string json formatted string if not admin user.
*/ */
public static function checkAdminUser() { public static function checkAdminUser() {
return(\OC_JSON::checkAdminUser()); \OC_JSON::checkAdminUser();
} }
/** /**
@ -177,4 +177,12 @@ class JSON {
public static function encode($data) { public static function encode($data) {
return(\OC_JSON::encode($data)); return(\OC_JSON::encode($data));
} }
/**
* Check is a given user exists - send json error msg if not
* @param string $user
*/
public static function checkUserExists($user) {
\OC_JSON::checkUserExists($user);
}
} }

View File

@ -347,20 +347,29 @@ class Share {
} }
/** /**
* Get the item shared by a token * Based on the given token the share information will be returned - password protected shares will be verified
* @param string token * @param string $token
* @return Item * @return array | bool false will be returned in case the token is unknown or unauthorized
*/ */
public static function getShareByToken($token) { public static function getShareByToken($token, $checkPasswordProtection = true) {
$query = \OC_DB::prepare('SELECT * FROM `*PREFIX*share` WHERE `token` = ?', 1); $query = \OC_DB::prepare('SELECT * FROM `*PREFIX*share` WHERE `token` = ?', 1);
$result = $query->execute(array($token)); $result = $query->execute(array($token));
if (\OC_DB::isError($result)) { if (\OC_DB::isError($result)) {
\OC_Log::write('OCP\Share', \OC_DB::getErrorMessage($result) . ', token=' . $token, \OC_Log::ERROR); \OC_Log::write('OCP\Share', \OC_DB::getErrorMessage($result) . ', token=' . $token, \OC_Log::ERROR);
} }
$row = $result->fetchRow(); $row = $result->fetchRow();
if ($row === false) {
return false;
}
if (is_array($row) and self::expireItem($row)) { if (is_array($row) and self::expireItem($row)) {
return false; return false;
} }
// password protected shares need to be authenticated
if ($checkPasswordProtection && !\OCP\Share::checkPasswordProtectedShare($row)) {
return false;
}
return $row; return $row;
} }
@ -655,7 +664,15 @@ class Share {
* @return Returns true on success or false on failure * @return Returns true on success or false on failure
*/ */
public static function unshareAll($itemType, $itemSource) { public static function unshareAll($itemType, $itemSource) {
if ($shares = self::getItemShared($itemType, $itemSource)) { // Get all of the owners of shares of this item.
$query = \OC_DB::prepare( 'SELECT `uid_owner` from `*PREFIX*share` WHERE `item_type`=? AND `item_source`=?' );
$result = $query->execute(array($itemType, $itemSource));
$shares = array();
// Add each owner's shares to the array of all shares for this item.
while ($row = $result->fetchRow()) {
$shares = array_merge($shares, self::getItems($itemType, $itemSource, null, null, $row['uid_owner']));
}
if (!empty($shares)) {
// Pass all the vars we have for now, they may be useful // Pass all the vars we have for now, they may be useful
$hookParams = array( $hookParams = array(
'itemType' => $itemType, 'itemType' => $itemType,
@ -1880,6 +1897,34 @@ class Share {
} }
} }
/**
* In case a password protected link is not yet authenticated this function will return false
*
* @param array $linkItem
* @return bool
*/
public static function checkPasswordProtectedShare(array $linkItem) {
if (!isset($linkItem['share_with'])) {
return true;
}
if (!isset($linkItem['share_type'])) {
return true;
}
if (!isset($linkItem['id'])) {
return true;
}
if ($linkItem['share_type'] != \OCP\Share::SHARE_TYPE_LINK) {
return true;
}
if ( \OC::$session->exists('public_link_authenticated')
&& \OC::$session->get('public_link_authenticated') === $linkItem['id'] ) {
return true;
}
return false;
}
} }
/** /**

View File

@ -131,6 +131,12 @@ span.version { margin-left:1em; margin-right:1em; color:#555; }
.appslink { text-decoration: underline; } .appslink { text-decoration: underline; }
.score { color:#666; font-weight:bold; font-size:0.8em; } .score { color:#666; font-weight:bold; font-size:0.8em; }
.appinfo .documentation {
margin-top: 1em;
margin-bottom: 1em;
}
/* LOG */ /* LOG */
#log { white-space:normal; } #log { white-space:normal; }
#lessLog { display:none; } #lessLog { display:none; }

View File

@ -37,6 +37,30 @@ OC.Settings.Apps = OC.Settings.Apps || {
} }
page.find('span.licence').text(appLicense); page.find('span.licence').text(appLicense);
var userDocumentation = false;
var adminDocumentation = false;
if (typeof(app.documentation) !== 'undefined') {
if (typeof(app.documentation.user) !== 'undefined') {
userDocumentation = true;
page.find('span.userDocumentation').html("<a id='userDocumentation' href='" + app.documentation.user + "'>" + t('settings', 'User Documentation') + "</a>");
page.find('p.documentation').show();
}
if (typeof(app.documentation.admin) !== 'undefined') {
adminDocumentation = true;
page.find('span.adminDocumentation').html("<a id='adminDocumentation' href='" + app.documentation.admin + "'>" + t('settings', 'Admin Documentation') + "</a>");
page.find('p.documentation').show();
}
if(userDocumentation && adminDocumentation) {
page.find('span.userDocumentation').after(', ');
}
}
if (typeof(app.website) !== 'undefined') {
page.find('p.website').show();
page.find('a#websitelink').attr('href', app.website);
}
if (app.update !== false) { if (app.update !== false) {
page.find('input.update').show(); page.find('input.update').show();
page.find('input.update').data('appid', app.id); page.find('input.update').data('appid', app.id);
@ -51,8 +75,8 @@ OC.Settings.Apps = OC.Settings.Apps || {
page.find('input.enable').data('active', app.active); page.find('input.enable').data('active', app.active);
if (app.internal === false) { if (app.internal === false) {
page.find('span.score').show(); page.find('span.score').show();
page.find('p.appslink').show(); page.find('p.appstore').show();
page.find('a').attr('href', 'http://apps.owncloud.com/content/show.php?content=' + app.id); page.find('a#appstorelink').attr('href', 'http://apps.owncloud.com/content/show.php?content=' + app.id);
page.find('small.externalapp').hide(); page.find('small.externalapp').hide();
} else { } else {
page.find('p.appslink').hide(); page.find('p.appslink').hide();
@ -110,7 +134,7 @@ OC.Settings.Apps = OC.Settings.Apps || {
element.val(t('settings','Disable')); element.val(t('settings','Disable'));
} }
},'json') },'json')
.fail(function() { .fail(function() {
OC.Settings.Apps.showErrorMessage(t('settings', 'Error while enabling app')); OC.Settings.Apps.showErrorMessage(t('settings', 'Error while enabling app'));
appitem.data('errormsg', t('settings', 'Error while enabling app')); appitem.data('errormsg', t('settings', 'Error while enabling app'));
appitem.data('active',false); appitem.data('active',false);

View File

@ -44,7 +44,7 @@ var UserList = {
// Provide user with option to undo // Provide user with option to undo
$('#notification').data('deleteuser', true); $('#notification').data('deleteuser', true);
OC.Notification.showHtml(t('users', 'deleted') + ' ' + escapeHTML(uid) + '<span class="undo">' + t('users', 'undo') + '</span>'); OC.Notification.showHtml(t('settings', 'deleted') + ' ' + escapeHTML(uid) + '<span class="undo">' + t('settings', 'undo') + '</span>');
}, },
/** /**

View File

@ -34,9 +34,16 @@
class="version"></span><small class="externalapp" style="visibility:hidden;"></small></h3> class="version"></span><small class="externalapp" style="visibility:hidden;"></small></h3>
<span class="score"></span> <span class="score"></span>
<p class="description"></p> <p class="description"></p>
<p class="documentation hidden">
<?php p($l->t("Documentation:"));?>
<span class="userDocumentation appslink"></span>
<span class="adminDocumentation appslink"></span>
</p>
<img src="" class="preview hidden" /> <img src="" class="preview hidden" />
<p class="appslink hidden"><a href="#" target="_blank"><?php <p class="appslink appstore hidden"><a id="appstorelink" href="#" target="_blank"><?php
p($l->t('See application page at apps.owncloud.com'));?></a></p> p($l->t('See application page at apps.owncloud.com'));?></a></p>
<p class="appslink website hidden"><a id="websitelink" href="#" target="_blank"><?php
p($l->t('See application website'));?></a></p>
<p class="license hidden"><?php <p class="license hidden"><?php
print_unescaped($l->t('<span class="licence"></span>-licensed by <span class="author"></span>'));?></p> print_unescaped($l->t('<span class="licence"></span>-licensed by <span class="author"></span>'));?></p>
<input class="enable hidden" type="submit" /> <input class="enable hidden" type="submit" />

View File

@ -21,6 +21,7 @@
<autoincrement>1</autoincrement> <autoincrement>1</autoincrement>
<unsigned>true</unsigned> <unsigned>true</unsigned>
<length>4</length> <length>4</length>
<comments>This is the id</comments>
</field> </field>
<field> <field>

View File

@ -8,16 +8,17 @@
require_once __DIR__.'/../lib/base.php'; require_once __DIR__.'/../lib/base.php';
OC_App::enable('files_sharing'); function enableApp($app) {
OC_App::enable('files_encryption'); try {
OC_App::enable('user_ldap'); OC_App::enable($app);
OC_App::enable('calendar'); } catch (Exception $e) {
OC_App::enable('contacts'); echo $e;
OC_App::enable('apptemplateadvanced'); }
OC_App::enable('appframework'); }
#OC_App::enable('files_archive');
#OC_App::enable('mozilla_sync'); enableApp('files_sharing');
#OC_App::enable('news'); enableApp('files_encryption');
#OC_App::enable('provisioning_api'); //enableApp('files_external');
#OC_App::enable('user_external'); enableApp('user_ldap');
enableApp('files_versions');

View File

@ -169,8 +169,9 @@ class Cache extends \PHPUnit_Framework_TestCase {
$this->assertEquals(916, $this->cache->calculateFolderSize($file1)); $this->assertEquals(916, $this->cache->calculateFolderSize($file1));
// direct cache entry retrieval returns the original values // direct cache entry retrieval returns the original values
$this->assertEquals(1025, $this->cache->get($file1)['size']); $entry = $this->cache->get($file1);
$this->assertEquals(916, $this->cache->get($file1)['unencrypted_size']); $this->assertEquals(1025, $entry['size']);
$this->assertEquals(916, $entry['unencrypted_size']);
$this->cache->remove($file2); $this->cache->remove($file2);
$this->cache->remove($file3); $this->cache->remove($file3);

View File

@ -59,6 +59,20 @@ class Quota extends \Test\Files\Storage\Storage {
$this->assertEquals('foobarqwe', $instance->file_get_contents('foo')); $this->assertEquals('foobarqwe', $instance->file_get_contents('foo'));
} }
public function testReturnFalseWhenFopenFailed(){
$failStorage = $this->getMock(
'\OC\Files\Storage\Local',
array('fopen'),
array(array('datadir' => $this->tmpDir)));
$failStorage->expects($this->any())
->method('fopen')
->will($this->returnValue(false));
$instance = new \OC\Files\Storage\Wrapper\Quota(array('storage' => $failStorage, 'quota' => 1000));
$this->assertFalse($instance->fopen('failedfopen', 'r'));
}
public function testReturnRegularStreamOnRead(){ public function testReturnRegularStreamOnRead(){
$instance = $this->getLimitedStorage(9); $instance = $this->getLimitedStorage(9);
@ -71,6 +85,11 @@ class Quota extends \Test\Files\Storage\Storage {
$meta = stream_get_meta_data($stream); $meta = stream_get_meta_data($stream);
$this->assertEquals('plainfile', $meta['wrapper_type']); $this->assertEquals('plainfile', $meta['wrapper_type']);
fclose($stream); fclose($stream);
$stream = $instance->fopen('foo', 'rb');
$meta = stream_get_meta_data($stream);
$this->assertEquals('plainfile', $meta['wrapper_type']);
fclose($stream);
} }
public function testReturnQuotaStreamOnWrite(){ public function testReturnQuotaStreamOnWrite(){

View File

@ -25,6 +25,8 @@ class Test_Share extends PHPUnit_Framework_TestCase {
protected $userBackend; protected $userBackend;
protected $user1; protected $user1;
protected $user2; protected $user2;
protected $user3;
protected $user4;
protected $groupBackend; protected $groupBackend;
protected $group1; protected $group1;
protected $group2; protected $group2;
@ -149,6 +151,26 @@ class Test_Share extends PHPUnit_Framework_TestCase {
); );
} }
protected function shareUserTestFileWithUser($sharer, $receiver) {
OC_User::setUserId($sharer);
$this->assertTrue(
OCP\Share::shareItem('test', 'test.txt', OCP\Share::SHARE_TYPE_USER, $receiver, OCP\PERMISSION_READ | OCP\PERMISSION_SHARE),
'Failed asserting that ' . $sharer . ' successfully shared text.txt with ' . $receiver . '.'
);
$this->assertContains(
'test.txt',
OCP\Share::getItemShared('test', 'test.txt', Test_Share_Backend::FORMAT_SOURCE),
'Failed asserting that test.txt is a shared file of ' . $sharer . '.'
);
OC_User::setUserId($receiver);
$this->assertContains(
'test.txt',
OCP\Share::getItemSharedWith('test', 'test.txt', Test_Share_Backend::FORMAT_SOURCE),
'Failed asserting that ' . $receiver . ' has access to test.txt after initial sharing.'
);
}
public function testShareWithUser() { public function testShareWithUser() {
// Invalid shares // Invalid shares
$message = 'Sharing test.txt failed, because the user '.$this->user1.' is the item owner'; $message = 'Sharing test.txt failed, because the user '.$this->user1.' is the item owner';
@ -585,25 +607,95 @@ class Test_Share extends PHPUnit_Framework_TestCase {
} }
public function testUnshareAll() { public function testUnshareAll() {
$this->shareUserOneTestFileWithUserTwo(); $this->shareUserTestFileWithUser($this->user1, $this->user2);
$this->shareUserTestFileWithUser($this->user2, $this->user3);
$this->shareUserTestFileWithUser($this->user3, $this->user4);
$this->shareUserOneTestFileWithGroupOne(); $this->shareUserOneTestFileWithGroupOne();
OC_User::setUserId($this->user1); OC_User::setUserId($this->user1);
$this->assertEquals( $this->assertEquals(
array('test.txt', 'test.txt'), array('test.txt', 'test.txt'),
OCP\Share::getItemsShared('test', 'test.txt'), OCP\Share::getItemsShared('test', 'test.txt'),
'Failed asserting that the test.txt file is shared exactly two times.' 'Failed asserting that the test.txt file is shared exactly two times by user1.'
);
OC_User::setUserId($this->user2);
$this->assertEquals(
array('test.txt'),
OCP\Share::getItemsShared('test', 'test.txt'),
'Failed asserting that the test.txt file is shared exactly once by user2.'
);
OC_User::setUserId($this->user3);
$this->assertEquals(
array('test.txt'),
OCP\Share::getItemsShared('test', 'test.txt'),
'Failed asserting that the test.txt file is shared exactly once by user3.'
); );
$this->assertTrue( $this->assertTrue(
OCP\Share::unshareAll('test', 'test.txt'), OCP\Share::unshareAll('test', 'test.txt'),
'Failed asserting that user 1 successfully unshared all shares of the test.txt share.' 'Failed asserting that user 3 successfully unshared all shares of the test.txt share.'
); );
$this->assertEquals( $this->assertEquals(
array(), array(),
OCP\Share::getItemsShared('test'), OCP\Share::getItemsShared('test'),
'Failed asserting that both shares of the test.txt file have been removed.' 'Failed asserting that the share of the test.txt file by user 3 has been removed.'
);
OC_User::setUserId($this->user1);
$this->assertEquals(
array(),
OCP\Share::getItemsShared('test'),
'Failed asserting that both shares of the test.txt file by user 1 have been removed.'
);
OC_User::setUserId($this->user2);
$this->assertEquals(
array(),
OCP\Share::getItemsShared('test'),
'Failed asserting that the share of the test.txt file by user 2 has been removed.'
); );
} }
/**
* @dataProvider checkPasswordProtectedShareDataProvider
* @param $expected
* @param $item
*/
public function testCheckPasswordProtectedShare($expected, $item) {
\OC::$session->set('public_link_authenticated', 100);
$result = \OCP\Share::checkPasswordProtectedShare($item);
$this->assertEquals($expected, $result);
}
function checkPasswordProtectedShareDataProvider() {
return array(
array(true, array()),
array(true, array('share_with' => null)),
array(true, array('share_with' => '')),
array(true, array('share_with' => '1234567890', 'share_type' => '1')),
array(true, array('share_with' => '1234567890', 'share_type' => 1)),
array(true, array('share_with' => '1234567890', 'share_type' => '3', 'id' => 100)),
array(true, array('share_with' => '1234567890', 'share_type' => 3, 'id' => 100)),
array(false, array('share_with' => '1234567890', 'share_type' => '3', 'id' => 101)),
array(false, array('share_with' => '1234567890', 'share_type' => 3, 'id' => 101)),
);
/*
if (!isset($linkItem['share_with'])) {
return true;
}
if ($linkItem['share_type'] != \OCP\Share::SHARE_TYPE_LINK) {
return true;
}
if ( \OC::$session->exists('public_link_authenticated')
&& \OC::$session->get('public_link_authenticated') === $linkItem['id'] ) {
return true;
}
* */
}
} }