Merge branch 'master' into avater_with_encryption
This commit is contained in:
commit
25320f19df
|
@ -239,14 +239,6 @@ table td.filename form { font-size:.85em; margin-left:3em; margin-right:3em; }
|
||||||
top: 14px;
|
top: 14px;
|
||||||
right: 0;
|
right: 0;
|
||||||
}
|
}
|
||||||
#fileList tr:hover .fileactions { /* background to distinguish when overlaying with file names */
|
|
||||||
background-color: rgba(240,240,240,0.898);
|
|
||||||
box-shadow: -5px 0 7px rgba(240,240,240,0.898);
|
|
||||||
}
|
|
||||||
#fileList tr.selected:hover .fileactions, #fileList tr.mouseOver .fileactions { /* slightly darker color for selected rows */
|
|
||||||
background-color: rgba(230,230,230,.9);
|
|
||||||
box-shadow: -5px 0 7px rgba(230,230,230,.9);
|
|
||||||
}
|
|
||||||
|
|
||||||
#fileList img.move2trash { display:inline; margin:-.5em 0; padding:1em .5em 1em .5em !important; float:right; }
|
#fileList img.move2trash { display:inline; margin:-.5em 0; padding:1em .5em 1em .5em !important; float:right; }
|
||||||
#fileList a.action.delete {
|
#fileList a.action.delete {
|
||||||
|
|
|
@ -47,7 +47,8 @@ class Proxy extends \OC_FileProxy {
|
||||||
*/
|
*/
|
||||||
private static function shouldEncrypt($path) {
|
private static function shouldEncrypt($path) {
|
||||||
|
|
||||||
if (\OCP\App::isEnabled('files_encryption') === false || Crypt::mode() !== 'server') {
|
if (\OCP\App::isEnabled('files_encryption') === false || Crypt::mode() !== 'server' ||
|
||||||
|
strpos($path, '/' . \OCP\User::getUser() . '/files') !== 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<fieldset class="personalblock">
|
<fieldset class="personalblock">
|
||||||
<h2><?php p($l->t('External Storage')); ?></h2>
|
<h2><?php p($l->t('External Storage')); ?></h2>
|
||||||
<?php if (isset($_['dependencies']) and ($_['dependencies']<>'')) print_unescaped(''.$_['dependencies'].''); ?>
|
<?php if (isset($_['dependencies']) and ($_['dependencies']<>'')) print_unescaped(''.$_['dependencies'].''); ?>
|
||||||
<table id="externalStorage" data-admin='<?php print_unescaped(json_encode($_['isAdminPage'])); ?>'>
|
<table id="externalStorage" class="grid" data-admin='<?php print_unescaped(json_encode($_['isAdminPage'])); ?>'>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th></th>
|
<th></th>
|
||||||
|
|
|
@ -31,11 +31,11 @@ class Api {
|
||||||
* @return \OC_OCS_Result share information
|
* @return \OC_OCS_Result share information
|
||||||
*/
|
*/
|
||||||
public static function getAllShares($params) {
|
public static function getAllShares($params) {
|
||||||
|
|
||||||
// if a file is specified, get the share for this file
|
// if a file is specified, get the share for this file
|
||||||
if (isset($_GET['path'])) {
|
if (isset($_GET['path'])) {
|
||||||
$params['itemSource'] = self::getFileId($_GET['path']);
|
$params['itemSource'] = self::getFileId($_GET['path']);
|
||||||
$params['path'] = $_GET['path'];
|
$params['path'] = $_GET['path'];
|
||||||
|
$params['itemType'] = self::getItemType($_GET['path']);
|
||||||
if (isset($_GET['subfiles']) && $_GET['subfiles'] === 'true') {
|
if (isset($_GET['subfiles']) && $_GET['subfiles'] === 'true') {
|
||||||
return self::getSharesFromFolder($params);
|
return self::getSharesFromFolder($params);
|
||||||
}
|
}
|
||||||
|
@ -59,20 +59,22 @@ class Api {
|
||||||
* @return \OC_OCS_Result share information
|
* @return \OC_OCS_Result share information
|
||||||
*/
|
*/
|
||||||
public static function getShare($params) {
|
public static function getShare($params) {
|
||||||
|
|
||||||
// either the $params already contains a itemSource if we come from
|
// either the $params already contains a itemSource if we come from
|
||||||
// getAllShare() or we need to translate the shareID to a itemSource
|
// getAllShare() or we need to translate the shareID to a itemSource
|
||||||
if(isset($params['itemSource'])) {
|
if(isset($params['itemSource'])) {
|
||||||
$itemSource = $params['itemSource'];
|
$itemSource = $params['itemSource'];
|
||||||
|
$itemType = $params['itemType'];
|
||||||
$getSpecificShare = true;
|
$getSpecificShare = true;
|
||||||
} else {
|
} else {
|
||||||
$s = self::getShareFromId($params['id']);
|
$s = self::getShareFromId($params['id']);
|
||||||
$itemSource = $s['item_source'];
|
$itemSource = $s['item_source'];
|
||||||
|
$itemType = $s['item_type'];
|
||||||
$getSpecificShare = false;
|
$getSpecificShare = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($itemSource !== null) {
|
if ($itemSource !== null) {
|
||||||
$shares = \OCP\Share::getItemShared('file', $itemSource);
|
$shares = \OCP\Share::getItemShared($itemType, $itemSource);
|
||||||
|
$reshare = \OCP\Share::getItemSharedWithBySource($itemType, $itemSource);
|
||||||
// if a specific share was specified only return this one
|
// if a specific share was specified only return this one
|
||||||
if ($getSpecificShare === false) {
|
if ($getSpecificShare === false) {
|
||||||
foreach ($shares as $share) {
|
foreach ($shares as $share) {
|
||||||
|
@ -82,6 +84,10 @@ class Api {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if ($reshare) {
|
||||||
|
$shares['received_from'] = $reshare['uid_owner'];
|
||||||
|
$shares['received_from_displayname'] = \OCP\User::getDisplayName($reshare['uid_owner']);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
$shares = null;
|
$shares = null;
|
||||||
}
|
}
|
||||||
|
@ -110,7 +116,14 @@ class Api {
|
||||||
|
|
||||||
$result = array();
|
$result = array();
|
||||||
foreach ($content as $file) {
|
foreach ($content as $file) {
|
||||||
$share = \OCP\Share::getItemShared('file', $file['fileid']);
|
// workaround because folders are named 'dir' in this context
|
||||||
|
$itemType = $file['type'] === 'file' ? 'file' : 'folder';
|
||||||
|
$share = \OCP\Share::getItemShared($itemType, $file['fileid']);
|
||||||
|
$reshare = \OCP\Share::getItemSharedWithBySource($itemType, $file['fileid']);
|
||||||
|
if ($reshare) {
|
||||||
|
$share['received_from'] = $reshare['uid_owner'];
|
||||||
|
$share['received_from_displayname'] = \OCP\User::getDisplayName($reshare['uid_owner']);
|
||||||
|
}
|
||||||
if ($share) {
|
if ($share) {
|
||||||
$share['filename'] = $file['name'];
|
$share['filename'] = $file['name'];
|
||||||
$result[] = $share;
|
$result[] = $share;
|
||||||
|
@ -132,7 +145,6 @@ class Api {
|
||||||
if($path === null) {
|
if($path === null) {
|
||||||
return new \OC_OCS_Result(null, 400, "please specify a file or folder path");
|
return new \OC_OCS_Result(null, 400, "please specify a file or folder path");
|
||||||
}
|
}
|
||||||
|
|
||||||
$itemSource = self::getFileId($path);
|
$itemSource = self::getFileId($path);
|
||||||
$itemType = self::getItemType($path);
|
$itemType = self::getItemType($path);
|
||||||
|
|
||||||
|
@ -184,7 +196,7 @@ class Api {
|
||||||
if ($token) {
|
if ($token) {
|
||||||
$data = array();
|
$data = array();
|
||||||
$data['id'] = 'unknown';
|
$data['id'] = 'unknown';
|
||||||
$shares = \OCP\Share::getItemShared('file', $itemSource);
|
$shares = \OCP\Share::getItemShared($itemType, $itemSource);
|
||||||
if(is_string($token)) { //public link share
|
if(is_string($token)) { //public link share
|
||||||
foreach ($shares as $share) {
|
foreach ($shares as $share) {
|
||||||
if ($share['token'] === $token) {
|
if ($share['token'] === $token) {
|
||||||
|
@ -414,7 +426,6 @@ class Api {
|
||||||
|
|
||||||
$view = new \OC\Files\View('/'.\OCP\User::getUser().'/files');
|
$view = new \OC\Files\View('/'.\OCP\User::getUser().'/files');
|
||||||
$fileId = null;
|
$fileId = null;
|
||||||
|
|
||||||
$fileInfo = $view->getFileInfo($path);
|
$fileInfo = $view->getFileInfo($path);
|
||||||
if ($fileInfo) {
|
if ($fileInfo) {
|
||||||
$fileId = $fileInfo['fileid'];
|
$fileId = $fileInfo['fileid'];
|
||||||
|
|
|
@ -197,7 +197,8 @@ class Test_Files_Sharing_Api extends \PHPUnit_Framework_TestCase {
|
||||||
\OCP\Share::shareItem('file', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_LINK,
|
\OCP\Share::shareItem('file', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_LINK,
|
||||||
null, 1);
|
null, 1);
|
||||||
|
|
||||||
$params = array('itemSource' => $fileInfo['fileid']);
|
$params = array('itemSource' => $fileInfo['fileid'],
|
||||||
|
'itemType' => 'file');
|
||||||
|
|
||||||
$result = Share\Api::getShare($params);
|
$result = Share\Api::getShare($params);
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,24 @@ class File {
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the size of the stored/cached data
|
||||||
|
*
|
||||||
|
* @param $key
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function size($key) {
|
||||||
|
$result = 0;
|
||||||
|
$proxyStatus = \OC_FileProxy::$enabled;
|
||||||
|
\OC_FileProxy::$enabled = false;
|
||||||
|
if ($this->hasKey($key)) {
|
||||||
|
$storage = $this->getStorage();
|
||||||
|
$result = $storage->filesize($key);
|
||||||
|
}
|
||||||
|
\OC_FileProxy::$enabled = $proxyStatus;
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
public function set($key, $value, $ttl=0) {
|
public function set($key, $value, $ttl=0) {
|
||||||
$storage = $this->getStorage();
|
$storage = $this->getStorage();
|
||||||
$result = false;
|
$result = false;
|
||||||
|
|
|
@ -71,7 +71,6 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa
|
||||||
$path = $this->path . '/' . $name;
|
$path = $this->path . '/' . $name;
|
||||||
$node = new OC_Connector_Sabre_File($path);
|
$node = new OC_Connector_Sabre_File($path);
|
||||||
return $node->put($data);
|
return $node->put($data);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -229,4 +228,5 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa
|
||||||
}
|
}
|
||||||
return $props;
|
return $props;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,23 +60,7 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D
|
||||||
|
|
||||||
// chunked handling
|
// chunked handling
|
||||||
if (isset($_SERVER['HTTP_OC_CHUNKED'])) {
|
if (isset($_SERVER['HTTP_OC_CHUNKED'])) {
|
||||||
|
return $this->createFileChunked($data);
|
||||||
list($path, $name) = \Sabre_DAV_URLUtil::splitPath($this->path);
|
|
||||||
|
|
||||||
$info = OC_FileChunking::decodeName($name);
|
|
||||||
if (empty($info)) {
|
|
||||||
throw new Sabre_DAV_Exception_NotImplemented();
|
|
||||||
}
|
|
||||||
|
|
||||||
$chunk_handler = new OC_FileChunking($info);
|
|
||||||
$chunk_handler->store($info['index'], $data);
|
|
||||||
if ($chunk_handler->isComplete()) {
|
|
||||||
$newPath = $path . '/' . $info['name'];
|
|
||||||
$chunk_handler->file_assemble($newPath);
|
|
||||||
return $this->getETagPropertyForPath($newPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// mark file as partial while uploading (ignored by the scanner)
|
// mark file as partial while uploading (ignored by the scanner)
|
||||||
|
@ -214,4 +198,37 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D
|
||||||
return \OC\Files\Filesystem::getMimeType($this->path);
|
return \OC\Files\Filesystem::getMimeType($this->path);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function createFileChunked($data)
|
||||||
|
{
|
||||||
|
list($path, $name) = \Sabre_DAV_URLUtil::splitPath($this->path);
|
||||||
|
|
||||||
|
$info = OC_FileChunking::decodeName($name);
|
||||||
|
if (empty($info)) {
|
||||||
|
throw new Sabre_DAV_Exception_NotImplemented();
|
||||||
|
}
|
||||||
|
$chunk_handler = new OC_FileChunking($info);
|
||||||
|
$bytesWritten = $chunk_handler->store($info['index'], $data);
|
||||||
|
|
||||||
|
//detect aborted upload
|
||||||
|
if (isset ($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] === 'PUT' ) {
|
||||||
|
if (isset($_SERVER['CONTENT_LENGTH'])) {
|
||||||
|
$expected = $_SERVER['CONTENT_LENGTH'];
|
||||||
|
if ($bytesWritten != $expected) {
|
||||||
|
$chunk_handler->cleanup();
|
||||||
|
throw new Sabre_DAV_Exception_BadRequest(
|
||||||
|
'expected filesize ' . $expected . ' got ' . $bytesWritten);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($chunk_handler->isComplete()) {
|
||||||
|
$newPath = $path . '/' . $info['name'];
|
||||||
|
$chunk_handler->file_assemble($newPath);
|
||||||
|
return OC_Connector_Sabre_Node::getETagPropertyForPath($newPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,10 +34,19 @@ class OC_FileChunking {
|
||||||
return $this->cache;
|
return $this->cache;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stores the given $data under the given $key - the number of stored bytes is returned
|
||||||
|
*
|
||||||
|
* @param $index
|
||||||
|
* @param $data
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
public function store($index, $data) {
|
public function store($index, $data) {
|
||||||
$cache = $this->getCache();
|
$cache = $this->getCache();
|
||||||
$name = $this->getPrefix().$index;
|
$name = $this->getPrefix().$index;
|
||||||
$cache->set($name, $data);
|
$cache->set($name, $data);
|
||||||
|
|
||||||
|
return $cache->size($name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function isComplete() {
|
public function isComplete() {
|
||||||
|
@ -58,12 +67,24 @@ class OC_FileChunking {
|
||||||
$count = 0;
|
$count = 0;
|
||||||
for($i=0; $i < $this->info['chunkcount']; $i++) {
|
for($i=0; $i < $this->info['chunkcount']; $i++) {
|
||||||
$chunk = $cache->get($prefix.$i);
|
$chunk = $cache->get($prefix.$i);
|
||||||
$cache->remove($prefix.$i);
|
|
||||||
$count += fwrite($f, $chunk);
|
$count += fwrite($f, $chunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->cleanup();
|
||||||
return $count;
|
return $count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes all chunks which belong to this transmission
|
||||||
|
*/
|
||||||
|
public function cleanup() {
|
||||||
|
$cache = $this->getCache();
|
||||||
|
$prefix = $this->getPrefix();
|
||||||
|
for($i=0; $i < $this->info['chunkcount']; $i++) {
|
||||||
|
$cache->remove($prefix.$i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function signature_split($orgfile, $input) {
|
public function signature_split($orgfile, $input) {
|
||||||
$info = unpack('n', fread($input, 2));
|
$info = unpack('n', fread($input, 2));
|
||||||
$blocksize = $info[1];
|
$blocksize = $info[1];
|
||||||
|
|
|
@ -509,11 +509,11 @@ class OC_Helper {
|
||||||
*
|
*
|
||||||
* @param resource $source
|
* @param resource $source
|
||||||
* @param resource $target
|
* @param resource $target
|
||||||
* @return int the number of bytes copied
|
* @return array the number of bytes copied and result
|
||||||
*/
|
*/
|
||||||
public static function streamCopy($source, $target) {
|
public static function streamCopy($source, $target) {
|
||||||
if (!$source or !$target) {
|
if (!$source or !$target) {
|
||||||
return false;
|
return array(0, false);
|
||||||
}
|
}
|
||||||
$result = true;
|
$result = true;
|
||||||
$count = 0;
|
$count = 0;
|
||||||
|
|
|
@ -325,7 +325,7 @@ class OC_User {
|
||||||
return $backend->getLogoutAttribute();
|
return $backend->getLogoutAttribute();
|
||||||
}
|
}
|
||||||
|
|
||||||
return "href=" . link_to('', 'index.php') . "?logout=true";
|
return 'href="' . link_to('', 'index.php') . '?logout=true"';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -208,4 +208,38 @@ class Test_Helper extends PHPUnit_Framework_TestCase {
|
||||||
->will($this->returnValue(true)); // filename(1) (2) (3).ext exists
|
->will($this->returnValue(true)); // filename(1) (2) (3).ext exists
|
||||||
$this->assertEquals('dir/filename(1) (2) (4).ext', OC_Helper::buildNotExistingFileNameForView('dir', 'filename(1) (2) (3).ext', $viewMock));
|
$this->assertEquals('dir/filename(1) (2) (4).ext', OC_Helper::buildNotExistingFileNameForView('dir', 'filename(1) (2) (3).ext', $viewMock));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider streamCopyDataProvider
|
||||||
|
*/
|
||||||
|
public function testStreamCopy($expectedCount, $expectedResult, $source, $target) {
|
||||||
|
|
||||||
|
if (is_string($source)) {
|
||||||
|
$source = fopen($source, 'r');
|
||||||
|
}
|
||||||
|
if (is_string($target)) {
|
||||||
|
$target = fopen($target, 'w');
|
||||||
|
}
|
||||||
|
|
||||||
|
list($count, $result) = \OC_Helper::streamCopy($source, $target);
|
||||||
|
|
||||||
|
if (is_resource($source)) {
|
||||||
|
fclose($source);
|
||||||
|
}
|
||||||
|
if (is_resource($target)) {
|
||||||
|
fclose($target);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->assertSame($expectedCount, $count);
|
||||||
|
$this->assertSame($expectedResult, $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function streamCopyDataProvider() {
|
||||||
|
return array(
|
||||||
|
array(0, false, false, false),
|
||||||
|
array(0, false, \OC::$SERVERROOT . '/tests/data/lorem.txt', false),
|
||||||
|
array(446, true, \OC::$SERVERROOT . '/tests/data/lorem.txt', \OC::$SERVERROOT . '/tests/data/lorem-copy.txt'),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue