Merge branch 'master' into fixing-3942-master

Conflicts:
	apps/files/ajax/upload.php
This commit is contained in:
Thomas Müller 2013-07-06 00:02:11 +02:00
commit dad91c156f
16 changed files with 281 additions and 167 deletions

View File

@ -18,7 +18,6 @@ if (empty($_POST['dirToken'])) {
}
} else {
$linkItem = OCP\Share::getShareByToken($_POST['dirToken']);
if ($linkItem === false) {
OCP\JSON::error(array('data' => array_merge(array('message' => $l->t('Invalid Token')))));
die();
@ -31,6 +30,7 @@ if (empty($_POST['dirToken'])) {
$rootLinkItem = OCP\Share::resolveReShare($linkItem);
// Setup FS with owner
OC_Util::tearDownFS();
OC_Util::setupFS($rootLinkItem['uid_owner']);
// The token defines the target directory (security reasons)

View File

@ -476,10 +476,19 @@ class Hooks {
$util = new Util($view, $userId);
// Format paths to be relative to user files dir
$oldKeyfilePath = \OC\Files\Filesystem::normalizePath(
$userId . '/' . 'files_encryption' . '/' . 'keyfiles' . '/' . $params['oldpath']);
$newKeyfilePath = \OC\Files\Filesystem::normalizePath(
$userId . '/' . 'files_encryption' . '/' . 'keyfiles' . '/' . $params['newpath']);
if ($util->isSystemWideMountPoint($params['oldpath'])) {
$baseDir = 'files_encryption/';
$oldKeyfilePath = $baseDir . 'keyfiles/' . $params['oldpath'];
} else {
$baseDir = $userId . '/' . 'files_encryption/';
$oldKeyfilePath = $baseDir . 'keyfiles/' . $params['oldpath'];
}
if ($util->isSystemWideMountPoint($params['newpath'])) {
$newKeyfilePath = $baseDir . 'keyfiles/' . $params['newpath'];
} else {
$newKeyfilePath = $baseDir . 'keyfiles/' . $params['newpath'];
}
// add key ext if this is not an folder
if (!$view->is_dir($oldKeyfilePath)) {
@ -487,8 +496,9 @@ class Hooks {
$newKeyfilePath .= '.key';
// handle share-keys
$localKeyPath = $view->getLocalFile($userId . '/files_encryption/share-keys/' . $params['oldpath']);
$matches = glob(preg_quote($localKeyPath) . '*.shareKey');
$localKeyPath = $view->getLocalFile($baseDir . 'share-keys/' . $params['oldpath']);
$escapedPath = Helper::escapeGlobPattern($localKeyPath);
$matches = glob($escapedPath . '*.shareKey');
foreach ($matches as $src) {
$dst = \OC\Files\Filesystem::normalizePath(str_replace($params['oldpath'], $params['newpath'], $src));
@ -502,10 +512,8 @@ class Hooks {
} else {
// handle share-keys folders
$oldShareKeyfilePath = \OC\Files\Filesystem::normalizePath(
$userId . '/' . 'files_encryption' . '/' . 'share-keys' . '/' . $params['oldpath']);
$newShareKeyfilePath = \OC\Files\Filesystem::normalizePath(
$userId . '/' . 'files_encryption' . '/' . 'share-keys' . '/' . $params['newpath']);
$oldShareKeyfilePath = $baseDir . 'share-keys/' . $params['oldpath'];
$newShareKeyfilePath = $baseDir . 'share-keys/' . $params['newpath'];
// create destination folder if not exists
if (!$view->file_exists(dirname($newShareKeyfilePath))) {

View File

@ -218,7 +218,6 @@ class Helper {
exit();
}
/**
* check requirements for encryption app.
* @return bool true if requirements are met
@ -233,4 +232,14 @@ class Helper {
return (bool) $result;
}
/**
* @brief glob uses different pattern than regular expressions, escape glob pattern only
* @param unescaped path
* @return escaped path
*/
public static function escapeGlobPattern($path) {
return preg_replace('/(\*|\?|\[)/', '[$1]', $path);
}
}

View File

@ -126,7 +126,12 @@ class Keymanager {
$util = new Util($view, \OCP\User::getUser());
list($owner, $filename) = $util->getUidAndFilename($path);
// in case of system wide mount points the keys are stored directly in the data directory
if ($util->isSystemWideMountPoint($filename)) {
$basePath = '/files_encryption/keyfiles';
} else {
$basePath = '/' . $owner . '/files_encryption/keyfiles';
}
$targetPath = self::keySetPreparation($view, $filename, $basePath, $owner);
@ -233,7 +238,12 @@ class Keymanager {
list($owner, $filename) = $util->getUidAndFilename($filePath);
$filePath_f = ltrim($filename, '/');
// in case of system wide mount points the keys are stored directly in the data directory
if ($util->isSystemWideMountPoint($filename)) {
$keyfilePath = '/files_encryption/keyfiles/' . $filePath_f . '.key';
} else {
$keyfilePath = '/' . $owner . '/files_encryption/keyfiles/' . $filePath_f . '.key';
}
$proxyStatus = \OC_FileProxy::$enabled;
\OC_FileProxy::$enabled = false;
@ -267,7 +277,14 @@ class Keymanager {
public static function deleteFileKey(\OC_FilesystemView $view, $userId, $path) {
$trimmed = ltrim($path, '/');
$util = new Util($view, \OCP\User::getUser());
if($util->isSystemWideMountPoint($path)) {
$keyPath = '/files_encryption/keyfiles/' . $trimmed;
} else {
$keyPath = '/' . $userId . '/files_encryption/keyfiles/' . $trimmed;
}
$result = false;
@ -325,57 +342,26 @@ class Keymanager {
* @brief store share key
*
* @param \OC_FilesystemView $view
* @param string $path relative path of the file, including filename
* @param $userId
* @param string $path where the share key is stored
* @param $shareKey
* @internal param string $key
* @internal param string $dbClassName
* @return bool true/false
* @note The keyfile is not encrypted here. Client code must
* asymmetrically encrypt the keyfile before passing it to this method
*/
public static function setShareKey(\OC_FilesystemView $view, $path, $userId, $shareKey) {
// Here we need the currently logged in user, while userId can be a different user
$util = new Util($view, \OCP\User::getUser());
list($owner, $filename) = $util->getUidAndFilename($path);
$basePath = '/' . $owner . '/files_encryption/share-keys';
$shareKeyPath = self::keySetPreparation($view, $filename, $basePath, $owner);
// try reusing key file if part file
if (self::isPartialFilePath($shareKeyPath)) {
$writePath = $basePath . '/' . self::fixPartialFilePath($shareKeyPath) . '.' . $userId . '.shareKey';
} else {
$writePath = $basePath . '/' . $shareKeyPath . '.' . $userId . '.shareKey';
}
private static function setShareKey(\OC_FilesystemView $view, $path, $shareKey) {
$proxyStatus = \OC_FileProxy::$enabled;
\OC_FileProxy::$enabled = false;
$result = $view->file_put_contents($writePath, $shareKey);
$result = $view->file_put_contents($path, $shareKey);
\OC_FileProxy::$enabled = $proxyStatus;
if (
is_int($result)
&& $result > 0
) {
if (is_int($result) && $result > 0) {
return true;
} else {
return false;
}
}
/**
@ -389,23 +375,40 @@ class Keymanager {
// $shareKeys must be an array with the following format:
// [userId] => [encrypted key]
// Here we need the currently logged in user, while userId can be a different user
$util = new Util($view, \OCP\User::getUser());
list($owner, $filename) = $util->getUidAndFilename($path);
// in case of system wide mount points the keys are stored directly in the data directory
if ($util->isSystemWideMountPoint($filename)) {
$basePath = '/files_encryption/share-keys';
} else {
$basePath = '/' . $owner . '/files_encryption/share-keys';
}
$shareKeyPath = self::keySetPreparation($view, $filename, $basePath, $owner);
$result = true;
foreach ($shareKeys as $userId => $shareKey) {
if (!self::setShareKey($view, $path, $userId, $shareKey)) {
// try reusing key file if part file
if (self::isPartialFilePath($shareKeyPath)) {
$writePath = $basePath . '/' . self::fixPartialFilePath($shareKeyPath) . '.' . $userId . '.shareKey';
} else {
$writePath = $basePath . '/' . $shareKeyPath . '.' . $userId . '.shareKey';
}
if (!self::setShareKey($view, $writePath, $shareKey)) {
// If any of the keys are not set, flag false
$result = false;
}
}
// Returns false if any of the keys weren't set
return $result;
}
/**
@ -440,8 +443,13 @@ class Keymanager {
$util = new Util($view, \OCP\User::getUser());
list($owner, $filename) = $util->getUidAndFilename($filePath);
$shareKeyPath = \OC\Files\Filesystem::normalizePath(
'/' . $owner . '/files_encryption/share-keys/' . $filename . '.' . $userId . '.shareKey');
// in case of system wide mount points the keys are stored directly in the data directory
if ($util->isSystemWideMountPoint($filename)) {
$shareKeyPath = '/files_encryption/share-keys/' . $filename . '.' . $userId . '.shareKey';
} else {
$shareKeyPath = '/' . $owner . '/files_encryption/share-keys/' . $filename . '.' . $userId . '.shareKey';
}
if ($view->file_exists($shareKeyPath)) {
@ -467,11 +475,21 @@ class Keymanager {
*/
public static function delAllShareKeys(\OC_FilesystemView $view, $userId, $filePath) {
if ($view->is_dir($userId . '/files/' . $filePath)) {
$view->unlink($userId . '/files_encryption/share-keys/' . $filePath);
$util = new util($view, $userId);
if ($util->isSystemWideMountPoint($filePath)) {
$baseDir = '/files_encryption/share-keys/';
} else {
$localKeyPath = $view->getLocalFile($userId . '/files_encryption/share-keys/' . $filePath);
$matches = glob(preg_quote($localKeyPath) . '*.shareKey');
$baseDir = $userId . '/files_encryption/share-keys/';
}
if ($view->is_dir($userId . '/files/' . $filePath)) {
$view->unlink($baseDir . $filePath);
} else {
$localKeyPath = $view->getLocalFile($baseDir . $filePath);
$escapedPath = Helper::escapeGlobPattern($localKeyPath);
$matches = glob($escapedPath . '*.shareKey');
foreach ($matches as $ma) {
$result = unlink($ma);
if (!$result) {
@ -495,7 +513,11 @@ class Keymanager {
list($owner, $filename) = $util->getUidAndFilename($filePath);
if ($util->isSystemWideMountPoint($filename)) {
$shareKeyPath = \OC\Files\Filesystem::normalizePath('/files_encryption/share-keys/' . $filename);
} else {
$shareKeyPath = \OC\Files\Filesystem::normalizePath('/' . $owner . '/files_encryption/share-keys/' . $filename);
}
if ($view->is_dir($shareKeyPath)) {
@ -526,7 +548,10 @@ class Keymanager {
*/
private static function recursiveDelShareKeys($dir, $userIds) {
foreach ($userIds as $userId) {
$matches = glob(preg_quote($dir) . '/*' . preg_quote('.' . $userId . '.shareKey'));
$extension = '.' . $userId . '.shareKey';
$escapedDir = Helper::escapeGlobPattern($dir);
$escapedExtension = Helper::escapeGlobPattern($extension);
$matches = glob($escapedDir . '/*' . $escapedExtension);
}
/** @var $matches array */
foreach ($matches as $ma) {
@ -535,7 +560,7 @@ class Keymanager {
'Could not delete shareKey; does not exist: "' . $ma . '"', \OCP\Util::ERROR);
}
}
$subdirs = $directories = glob(preg_quote($dir) . '/*', GLOB_ONLYDIR);
$subdirs = $directories = glob($escapedDir . '/*', GLOB_ONLYDIR);
foreach ($subdirs as $subdir) {
self::recursiveDelShareKeys($subdir, $userIds);
}

View File

@ -992,13 +992,9 @@ class Util {
\OC_Appconfig::getValue('files_encryption', 'recoveryAdminEnabled')
&& $this->recoveryEnabledForUser()
) {
$recoveryEnabled = true;
} else {
$recoveryEnabled = false;
}
// Make sure that a share key is generated for the owner too
@ -1019,20 +1015,25 @@ class Util {
// If recovery is enabled, add the
// Admin UID to list of users to share to
if ($recoveryEnabled) {
// Find recoveryAdmin user ID
$recoveryKeyId = \OC_Appconfig::getValue('files_encryption', 'recoveryKeyId');
// Add recoveryAdmin to list of users sharing
$userIds[] = $recoveryKeyId;
}
// add current user if given
if ($currentUserId !== false) {
$userIds[] = $currentUserId;
}
// check if it is a group mount
if (\OCP\App::isEnabled("files_external")) {
$mount = \OC_Mount_Config::getSystemMountPoints();
foreach ($mount as $mountPoint => $data) {
if ($mountPoint == substr($ownerPath, 1, strlen($mountPoint))) {
$userIds = array_merge($userIds, $this->getUserWithAccessToMountPoint($data['applicable']['users'], $data['applicable']['groups']));
}
}
}
// Remove duplicate UIDs
@ -1042,6 +1043,20 @@ class Util {
}
private function getUserWithAccessToMountPoint($users, $groups) {
$result = array();
if (in_array('all', $users)) {
$result = \OCP\User::getUsers();
} else {
$result = array_merge($result, $users);
foreach ($groups as $group) {
$result = array_merge($result, \OC_Group::usersInGroup($group));
}
}
return $result;
}
/**
* @brief start migration mode to initially encrypt users data
* @return boolean
@ -1179,7 +1194,7 @@ class Util {
return array(
$fileOwnerUid,
$filename
\OC_Filesystem::normalizePath($filename)
);
}
@ -1547,4 +1562,21 @@ class Util {
return $relativePath;
}
/**
* @brief check if the file is stored on a system wide mount point
* @param $path relative to /data/user with leading '/'
* @return boolean
*/
public function isSystemWideMountPoint($path) {
if (\OCP\App::isEnabled("files_external")) {
$mount = \OC_Mount_Config::getSystemMountPoints();
foreach ($mount as $mountPoint => $data) {
if ($mountPoint == substr($path, 1, strlen($mountPoint))) {
return true;
}
}
}
return false;
}
}

View File

@ -219,7 +219,7 @@ class Test_Encryption_Util extends \PHPUnit_Framework_TestCase {
\OC_User::setUserId(\Test_Encryption_Util::TEST_ENCRYPTION_UTIL_USER1);
$filename = 'tmp-' . time() . '.test';
$filename = '/tmp-' . time() . '.test';
// Disable encryption proxy to prevent recursive calls
$proxyStatus = \OC_FileProxy::$enabled;

View File

@ -11,6 +11,8 @@ var form_data;
$(document).ready(function() {
$('#data-upload-form').tipsy({gravity:'ne', fade:true});
if (typeof FileActions !== 'undefined') {
var mimetype = $('#mimetype').val();
// Show file preview if previewer is available, images are already handled by the template

View File

@ -137,6 +137,9 @@ if (isset($path)) {
if (\OCP\App::isEnabled('files_encryption')) {
$allowPublicUploadEnabled = false;
}
if (isset($file)) {
$allowPublicUploadEnabled = false;
}
$tmpl->assign('allowPublicUploadEnabled', $allowPublicUploadEnabled);
$tmpl->assign('uploadMaxFilesize', $maxUploadFilesize);
$tmpl->assign('uploadMaxHumanFilesize', OCP\Util::humanFileSize($maxUploadFilesize));

View File

@ -36,9 +36,13 @@
<input type="hidden" id="uploadMaxFilesize" name="uploadMaxFilesize" value="<?php p($_['uploadMaxFilesize']) ?>" />
<input type="hidden" id="uploadMaxHumanFilesize" name="uploadMaxHumanFilesize" value="<?php p($_['uploadMaxHumanFilesize']) ?>" />
<input type="hidden" id="directory_path" name="directory_path" value="<?php p($_['directory_path']) ?>" />
<?php if($_['uploadMaxFilesize'] >= 0):?>
<input type="hidden" name="MAX_FILE_SIZE" id="max_upload"
value="<?php p($_['uploadMaxFilesize']) ?>">
<?php endif;?>
<div id="data-upload-form" class="button">
<div id="data-upload-form" class="button" 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>
<a href="#" id="publicUploadButtonMock" class="svg">
<span><?php p($l->t('Upload'))?></span>

View File

@ -171,13 +171,19 @@ class Trashbin {
list($owner, $ownerPath) = self::getUidAndFilename($file_path);
$util = new \OCA\Encryption\Util(new \OC_FilesystemView('/'), $user);
// disable proxy to prevent recursive calls
$proxyStatus = \OC_FileProxy::$enabled;
\OC_FileProxy::$enabled = false;
// retain key files
$keyfile = \OC\Files\Filesystem::normalizePath($owner . '/files_encryption/keyfiles/' . $ownerPath);
if ($util->isSystemWideMountPoint($ownerPath)) {
$baseDir = '/files_encryption/';
} else {
$baseDir = $owner . '/files_encryption/';
}
$keyfile = \OC\Files\Filesystem::normalizePath($baseDir . '/keyfiles/' . $ownerPath);
if ($rootView->is_dir($keyfile) || $rootView->file_exists($keyfile . '.key')) {
// move keyfiles
@ -191,7 +197,7 @@ class Trashbin {
}
// retain share keys
$sharekeys = \OC\Files\Filesystem::normalizePath($owner . '/files_encryption/share-keys/' . $ownerPath);
$sharekeys = \OC\Files\Filesystem::normalizePath($baseDir . '/share-keys/' . $ownerPath);
if ($rootView->is_dir($sharekeys)) {
$size += self::calculateSize(new \OC\Files\View($sharekeys));
@ -403,6 +409,14 @@ class Trashbin {
list($owner, $ownerPath) = self::getUidAndFilename($target);
$util = new \OCA\Encryption\Util(new \OC_FilesystemView('/'), $user);
if ($util->isSystemWideMountPoint($ownerPath)) {
$baseDir = '/files_encryption/';
} else {
$baseDir = $owner . '/files_encryption/';
}
$path_parts = pathinfo($file);
$source_location = $path_parts['dirname'];
@ -432,18 +446,18 @@ class Trashbin {
// handle keyfiles
$size += self::calculateSize(new \OC\Files\View($keyfile));
$rootView->rename($keyfile, $owner . '/files_encryption/keyfiles/' . $ownerPath);
$rootView->rename($keyfile, $baseDir . '/keyfiles/' . $ownerPath);
// handle share-keys
if ($timestamp) {
$sharekey .= '.d' . $timestamp;
}
$size += self::calculateSize(new \OC\Files\View($sharekey));
$rootView->rename($sharekey, $owner . '/files_encryption/share-keys/' . $ownerPath);
$rootView->rename($sharekey, $baseDir . '/share-keys/' . $ownerPath);
} else {
// handle keyfiles
$size += $rootView->filesize($keyfile);
$rootView->rename($keyfile, $owner . '/files_encryption/keyfiles/' . $ownerPath . '.key');
$rootView->rename($keyfile, $baseDir . '/keyfiles/' . $ownerPath . '.key');
// handle share-keys
$ownerShareKey = \OC\Files\Filesystem::normalizePath($user . '/files_trashbin/share-keys/' . $source_location . '/' . $filename . '.' . $user . '.shareKey');
@ -454,7 +468,7 @@ class Trashbin {
$size += $rootView->filesize($ownerShareKey);
// move only owners key
$rootView->rename($ownerShareKey, $owner . '/files_encryption/share-keys/' . $ownerPath . '.' . $user . '.shareKey');
$rootView->rename($ownerShareKey, $baseDir . '/share-keys/' . $ownerPath . '.' . $user . '.shareKey');
// try to re-share if file is shared
$filesystemView = new \OC_FilesystemView('/');

View File

@ -181,11 +181,13 @@ OC.Share={
html += '<div id="linkPass">';
html += '<input id="linkPassText" type="password" placeholder="'+t('core', 'Password')+'" />';
html += '</div>';
if (itemType === 'folder' && (possiblePermissions & OC.PERMISSION_CREATE)) {
html += '<div id="allowPublicUploadWrapper" style="display:none;">';
html += '<input type="checkbox" value="1" name="allowPublicUpload" id="sharingDialogAllowPublicUpload"' + ((allowPublicUploadStatus) ? 'checked="checked"' : '') + ' />';
html += '<label for="sharingDialogAllowPublicUpload">' + t('core', 'Allow Public Upload') + '</label>';
html += '</div></div>';
html += '<form id="emailPrivateLink" >';
html += '</div>';
}
html += '</div><form id="emailPrivateLink" >';
html += '<input id="email" style="display:none; width:62%;" value="" placeholder="'+t('core', 'Email link to person')+'" type="text" />';
html += '<input id="emailButton" style="display:none;" type="submit" value="'+t('core', 'Send')+'" />';
html += '</form>';

View File

@ -1,9 +1,9 @@
<?php
$defaults = new OC_Defaults();
print_unescaped($l->t("Hey there,\n\njust letting you know that %s shared %s with you.\nView it: %s\n\nCheers!", array($_['user_displayname'], $_['filename'], $_['link'])));
?>
--
ownCloud - <?php
print_unescaped($l->t("web services under your control"));
?>
http://ownCloud.org
<?php p($defaults->getName() . ' - ' . $defaults->getSlogan()); ?>
<?php print_unescaped("\n".$defaults->getBaseUrl());

View File

@ -1,3 +1,4 @@
<?php $defaults = new OC_Defaults() // initialize themable default strings and urls ?>
<table cellspacing="0" cellpadding="0" border="0" width="100%">
<tr><td>
<table cellspacing="0" cellpadding="0" border="0" width="600px">
@ -20,10 +21,9 @@ print_unescaped($l->t('Hey there,<br><br>just letting you know that %s shared »
<tr>
<td bgcolor="#f8f8f8" width="20px">&nbsp;</td>
<td bgcolor="#f8f8f8" style="font-weight:normal; font-size:0.8em; line-height:1.2em; font-family:verdana,'arial',sans;">--<br>
ownCloud - <?php
print_unescaped($l->t('web services under your control'));
?>
<br><a href="http://owncloud.org">http://ownCloud.org</a></td>
<?php p($defaults->getName()); ?> -
<?php p($defaults->getSlogan()); ?>
<br><a href="<?php print_unescaped($defaults->getBaseUrl()); ?>"><?php print_unescaped($defaults->getBaseUrl());?></a></td>
</tr>
<tr>
<td bgcolor="#f8f8f8" colspan="2">&nbsp;</td>

View File

@ -132,6 +132,9 @@ class OC_Config{
// read all file in config dir ending by config.php
$config_files = glob( OC::$SERVERROOT."/config/*.config.php");
if (!is_array($config_files)) {
$config_files = array();
}
//Filter only regular files
$config_files = array_filter($config_files, 'is_file');

View File

@ -340,6 +340,17 @@ class Share {
$parameters, -1, $includeCollections);
}
/**
* @param $itemType
* @param $itemSource
* @param $uid_owner
* @return mixed
*/
public static function getSharedItem($itemType, $itemSource, $uid_owner) {
return self::getItems($itemType, $itemSource, null, null, $uid_owner, self::FORMAT_NONE,
null, 1, false);
}
/**
* Get all users an item is shared with
* @param string Item type

View File

@ -132,6 +132,7 @@ class Scanner extends \PHPUnit_Framework_TestCase {
$this->scanner->scan('');
$oldData = $this->cache->get('');
$this->storage->unlink('folder/bar.txt');
$this->cache->put('folder', array('mtime' => $this->storage->filemtime('folder')));
$this->scanner->scan('', \OC\Files\Cache\Scanner::SCAN_SHALLOW, \OC\Files\Cache\Scanner::REUSE_SIZE);
$newData = $this->cache->get('');
$this->assertNotEquals($oldData['etag'], $newData['etag']);