Merge pull request #225 from nextcloud/stable9-upstream-sync
[Stable9] upstream sync
This commit is contained in:
commit
49a916fb46
|
@ -76,16 +76,26 @@ class FilesPlugin extends \Sabre\DAV\ServerPlugin {
|
||||||
*/
|
*/
|
||||||
private $fileView;
|
private $fileView;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var IRequest
|
||||||
|
*/
|
||||||
|
private $request;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param \Sabre\DAV\Tree $tree
|
* @param \Sabre\DAV\Tree $tree
|
||||||
* @param \OC\Files\View $view
|
* @param \OC\Files\View $view
|
||||||
|
* @param \OCP\IRequest $request
|
||||||
* @param bool $isPublic
|
* @param bool $isPublic
|
||||||
*/
|
*/
|
||||||
public function __construct(\Sabre\DAV\Tree $tree,
|
public function __construct(
|
||||||
|
\Sabre\DAV\Tree $tree,
|
||||||
\OC\Files\View $view,
|
\OC\Files\View $view,
|
||||||
$isPublic = false) {
|
\OCP\IRequest $request,
|
||||||
|
$isPublic = false
|
||||||
|
) {
|
||||||
$this->tree = $tree;
|
$this->tree = $tree;
|
||||||
$this->fileView = $view;
|
$this->fileView = $view;
|
||||||
|
$this->request = $request;
|
||||||
$this->isPublic = $isPublic;
|
$this->isPublic = $isPublic;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -193,7 +203,18 @@ class FilesPlugin extends \Sabre\DAV\ServerPlugin {
|
||||||
if (!($node instanceof IFile)) return;
|
if (!($node instanceof IFile)) return;
|
||||||
|
|
||||||
// adds a 'Content-Disposition: attachment' header
|
// adds a 'Content-Disposition: attachment' header
|
||||||
$response->addHeader('Content-Disposition', 'attachment');
|
$filename = $node->getName();
|
||||||
|
if ($this->request->isUserAgent(
|
||||||
|
[
|
||||||
|
\OC\AppFramework\Http\Request::USER_AGENT_IE,
|
||||||
|
\OC\AppFramework\Http\Request::USER_AGENT_ANDROID_MOBILE_CHROME,
|
||||||
|
\OC\AppFramework\Http\Request::USER_AGENT_FREEBOX,
|
||||||
|
])) {
|
||||||
|
$response->addHeader('Content-Disposition', 'attachment; filename="' . rawurlencode($filename) . '"');
|
||||||
|
} else {
|
||||||
|
$response->addHeader('Content-Disposition', 'attachment; filename*=UTF-8\'\'' . rawurlencode($filename)
|
||||||
|
. '; filename="' . rawurlencode($filename) . '"');
|
||||||
|
}
|
||||||
|
|
||||||
if ($node instanceof \OCA\DAV\Connector\Sabre\File) {
|
if ($node instanceof \OCA\DAV\Connector\Sabre\File) {
|
||||||
//Add OC-Checksum header
|
//Add OC-Checksum header
|
||||||
|
|
|
@ -137,7 +137,11 @@ class ServerFactory {
|
||||||
}
|
}
|
||||||
$objectTree->init($root, $view, $this->mountManager);
|
$objectTree->init($root, $view, $this->mountManager);
|
||||||
|
|
||||||
$server->addPlugin(new \OCA\DAV\Connector\Sabre\FilesPlugin($objectTree, $view));
|
$server->addPlugin(new \OCA\DAV\Connector\Sabre\FilesPlugin(
|
||||||
|
$objectTree,
|
||||||
|
$view,
|
||||||
|
$this->request
|
||||||
|
));
|
||||||
$server->addPlugin(new \OCA\DAV\Connector\Sabre\QuotaPlugin($view));
|
$server->addPlugin(new \OCA\DAV\Connector\Sabre\QuotaPlugin($view));
|
||||||
|
|
||||||
if($this->userSession->isLoggedIn()) {
|
if($this->userSession->isLoggedIn()) {
|
||||||
|
|
|
@ -125,7 +125,11 @@ class Server {
|
||||||
$user = \OC::$server->getUserSession()->getUser();
|
$user = \OC::$server->getUserSession()->getUser();
|
||||||
if (!is_null($user)) {
|
if (!is_null($user)) {
|
||||||
$view = \OC\Files\Filesystem::getView();
|
$view = \OC\Files\Filesystem::getView();
|
||||||
$this->server->addPlugin(new FilesPlugin($this->server->tree, $view));
|
$this->server->addPlugin(new FilesPlugin(
|
||||||
|
$this->server->tree,
|
||||||
|
$view,
|
||||||
|
$this->request
|
||||||
|
));
|
||||||
|
|
||||||
$this->server->addPlugin(
|
$this->server->addPlugin(
|
||||||
new \Sabre\DAV\PropertyStorage\Plugin(
|
new \Sabre\DAV\PropertyStorage\Plugin(
|
||||||
|
|
|
@ -72,8 +72,13 @@ class FilesPlugin extends \Test\TestCase {
|
||||||
$this->view = $this->getMockBuilder('\OC\Files\View')
|
$this->view = $this->getMockBuilder('\OC\Files\View')
|
||||||
->disableOriginalConstructor()
|
->disableOriginalConstructor()
|
||||||
->getMock();
|
->getMock();
|
||||||
|
$request = $this->getMock('\OCP\IRequest');
|
||||||
|
|
||||||
$this->plugin = new \OCA\DAV\Connector\Sabre\FilesPlugin($this->tree, $this->view);
|
$this->plugin = new \OCA\DAV\Connector\Sabre\FilesPlugin(
|
||||||
|
$this->tree,
|
||||||
|
$this->view,
|
||||||
|
$request
|
||||||
|
);
|
||||||
$this->plugin->initialize($this->server);
|
$this->plugin->initialize($this->server);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -237,7 +242,11 @@ class FilesPlugin extends \Test\TestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testGetPublicPermissions() {
|
public function testGetPublicPermissions() {
|
||||||
$this->plugin = new \OCA\DAV\Connector\Sabre\FilesPlugin($this->tree, $this->view, true);
|
$this->plugin = new \OCA\DAV\Connector\Sabre\FilesPlugin(
|
||||||
|
$this->tree,
|
||||||
|
$this->view,
|
||||||
|
$this->getMock('\OCP\IRequest'),
|
||||||
|
true);
|
||||||
$this->plugin->initialize($this->server);
|
$this->plugin->initialize($this->server);
|
||||||
|
|
||||||
$propFind = new \Sabre\DAV\PropFind(
|
$propFind = new \Sabre\DAV\PropFind(
|
||||||
|
|
|
@ -336,7 +336,11 @@ class FilesReportPlugin extends \Test\TestCase {
|
||||||
->method('getSize')
|
->method('getSize')
|
||||||
->will($this->returnValue(1024));
|
->will($this->returnValue(1024));
|
||||||
|
|
||||||
$this->server->addPlugin(new \OCA\DAV\Connector\Sabre\FilesPlugin($this->tree, $this->view));
|
$this->server->addPlugin(new \OCA\DAV\Connector\Sabre\FilesPlugin(
|
||||||
|
$this->tree,
|
||||||
|
$this->view,
|
||||||
|
$this->getMock('\OCP\IRequest')
|
||||||
|
));
|
||||||
$this->plugin->initialize($this->server);
|
$this->plugin->initialize($this->server);
|
||||||
$responses = $this->plugin->prepareResponses($requestedProps, [$node1, $node2]);
|
$responses = $this->plugin->prepareResponses($requestedProps, [$node1, $node2]);
|
||||||
|
|
||||||
|
|
|
@ -131,6 +131,7 @@ class GlobalStoragesController extends StoragesController {
|
||||||
* @param array $applicableUsers users for which to mount the storage
|
* @param array $applicableUsers users for which to mount the storage
|
||||||
* @param array $applicableGroups groups for which to mount the storage
|
* @param array $applicableGroups groups for which to mount the storage
|
||||||
* @param int $priority priority
|
* @param int $priority priority
|
||||||
|
* @param bool $testOnly whether to storage should only test the connection or do more things
|
||||||
*
|
*
|
||||||
* @return DataResponse
|
* @return DataResponse
|
||||||
*/
|
*/
|
||||||
|
@ -143,7 +144,8 @@ class GlobalStoragesController extends StoragesController {
|
||||||
$mountOptions,
|
$mountOptions,
|
||||||
$applicableUsers,
|
$applicableUsers,
|
||||||
$applicableGroups,
|
$applicableGroups,
|
||||||
$priority
|
$priority,
|
||||||
|
$testOnly = true
|
||||||
) {
|
) {
|
||||||
$storage = $this->createStorage(
|
$storage = $this->createStorage(
|
||||||
$mountPoint,
|
$mountPoint,
|
||||||
|
@ -176,7 +178,7 @@ class GlobalStoragesController extends StoragesController {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->updateStorageStatus($storage);
|
$this->updateStorageStatus($storage, $testOnly);
|
||||||
|
|
||||||
return new DataResponse(
|
return new DataResponse(
|
||||||
$storage,
|
$storage,
|
||||||
|
|
|
@ -240,8 +240,9 @@ abstract class StoragesController extends Controller {
|
||||||
* on whether the remote storage is available or not.
|
* on whether the remote storage is available or not.
|
||||||
*
|
*
|
||||||
* @param StorageConfig $storage storage configuration
|
* @param StorageConfig $storage storage configuration
|
||||||
|
* @param bool $testOnly whether to storage should only test the connection or do more things
|
||||||
*/
|
*/
|
||||||
protected function updateStorageStatus(StorageConfig &$storage) {
|
protected function updateStorageStatus(StorageConfig &$storage, $testOnly = true) {
|
||||||
try {
|
try {
|
||||||
$this->manipulateStorageConfig($storage);
|
$this->manipulateStorageConfig($storage);
|
||||||
|
|
||||||
|
@ -252,7 +253,8 @@ abstract class StoragesController extends Controller {
|
||||||
\OC_Mount_Config::getBackendStatus(
|
\OC_Mount_Config::getBackendStatus(
|
||||||
$backend->getStorageClass(),
|
$backend->getStorageClass(),
|
||||||
$storage->getBackendOptions(),
|
$storage->getBackendOptions(),
|
||||||
false
|
false,
|
||||||
|
$testOnly
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
} catch (InsufficientDataForMeaningfulAnswerException $e) {
|
} catch (InsufficientDataForMeaningfulAnswerException $e) {
|
||||||
|
@ -293,14 +295,15 @@ abstract class StoragesController extends Controller {
|
||||||
* Get an external storage entry.
|
* Get an external storage entry.
|
||||||
*
|
*
|
||||||
* @param int $id storage id
|
* @param int $id storage id
|
||||||
|
* @param bool $testOnly whether to storage should only test the connection or do more things
|
||||||
*
|
*
|
||||||
* @return DataResponse
|
* @return DataResponse
|
||||||
*/
|
*/
|
||||||
public function show($id) {
|
public function show($id, $testOnly = true) {
|
||||||
try {
|
try {
|
||||||
$storage = $this->service->getStorage($id);
|
$storage = $this->service->getStorage($id);
|
||||||
|
|
||||||
$this->updateStorageStatus($storage);
|
$this->updateStorageStatus($storage, $testOnly);
|
||||||
} catch (NotFoundException $e) {
|
} catch (NotFoundException $e) {
|
||||||
return new DataResponse(
|
return new DataResponse(
|
||||||
[
|
[
|
||||||
|
|
|
@ -106,15 +106,16 @@ class UserGlobalStoragesController extends StoragesController {
|
||||||
* Get an external storage entry.
|
* Get an external storage entry.
|
||||||
*
|
*
|
||||||
* @param int $id storage id
|
* @param int $id storage id
|
||||||
|
* @param bool $testOnly whether to storage should only test the connection or do more things
|
||||||
* @return DataResponse
|
* @return DataResponse
|
||||||
*
|
*
|
||||||
* @NoAdminRequired
|
* @NoAdminRequired
|
||||||
*/
|
*/
|
||||||
public function show($id) {
|
public function show($id, $testOnly = true) {
|
||||||
try {
|
try {
|
||||||
$storage = $this->service->getStorage($id);
|
$storage = $this->service->getStorage($id);
|
||||||
|
|
||||||
$this->updateStorageStatus($storage);
|
$this->updateStorageStatus($storage, $testOnly);
|
||||||
} catch (NotFoundException $e) {
|
} catch (NotFoundException $e) {
|
||||||
return new DataResponse(
|
return new DataResponse(
|
||||||
[
|
[
|
||||||
|
@ -138,6 +139,7 @@ class UserGlobalStoragesController extends StoragesController {
|
||||||
*
|
*
|
||||||
* @param int $id storage id
|
* @param int $id storage id
|
||||||
* @param array $backendOptions backend-specific options
|
* @param array $backendOptions backend-specific options
|
||||||
|
* @param bool $testOnly whether to storage should only test the connection or do more things
|
||||||
*
|
*
|
||||||
* @return DataResponse
|
* @return DataResponse
|
||||||
*
|
*
|
||||||
|
@ -145,7 +147,8 @@ class UserGlobalStoragesController extends StoragesController {
|
||||||
*/
|
*/
|
||||||
public function update(
|
public function update(
|
||||||
$id,
|
$id,
|
||||||
$backendOptions
|
$backendOptions,
|
||||||
|
$testOnly = true
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
$storage = $this->service->getStorage($id);
|
$storage = $this->service->getStorage($id);
|
||||||
|
@ -170,7 +173,7 @@ class UserGlobalStoragesController extends StoragesController {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->updateStorageStatus($storage);
|
$this->updateStorageStatus($storage, $testOnly);
|
||||||
$this->sanitizeStorage($storage);
|
$this->sanitizeStorage($storage);
|
||||||
|
|
||||||
return new DataResponse(
|
return new DataResponse(
|
||||||
|
|
|
@ -104,8 +104,8 @@ class UserStoragesController extends StoragesController {
|
||||||
*
|
*
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public function show($id) {
|
public function show($id, $testOnly = true) {
|
||||||
return parent::show($id);
|
return parent::show($id, $testOnly);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -162,6 +162,7 @@ class UserStoragesController extends StoragesController {
|
||||||
* @param string $authMechanism authentication mechanism identifier
|
* @param string $authMechanism authentication mechanism identifier
|
||||||
* @param array $backendOptions backend-specific options
|
* @param array $backendOptions backend-specific options
|
||||||
* @param array $mountOptions backend-specific mount options
|
* @param array $mountOptions backend-specific mount options
|
||||||
|
* @param bool $testOnly whether to storage should only test the connection or do more things
|
||||||
*
|
*
|
||||||
* @return DataResponse
|
* @return DataResponse
|
||||||
*
|
*
|
||||||
|
@ -173,7 +174,8 @@ class UserStoragesController extends StoragesController {
|
||||||
$backend,
|
$backend,
|
||||||
$authMechanism,
|
$authMechanism,
|
||||||
$backendOptions,
|
$backendOptions,
|
||||||
$mountOptions
|
$mountOptions,
|
||||||
|
$testOnly = true
|
||||||
) {
|
) {
|
||||||
$storage = $this->createStorage(
|
$storage = $this->createStorage(
|
||||||
$mountPoint,
|
$mountPoint,
|
||||||
|
@ -203,7 +205,7 @@ class UserStoragesController extends StoragesController {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->updateStorageStatus($storage);
|
$this->updateStorageStatus($storage, $testOnly);
|
||||||
|
|
||||||
return new DataResponse(
|
return new DataResponse(
|
||||||
$storage,
|
$storage,
|
||||||
|
|
|
@ -305,7 +305,8 @@ StorageConfig.prototype = {
|
||||||
mountPoint: this.mountPoint,
|
mountPoint: this.mountPoint,
|
||||||
backend: this.backend,
|
backend: this.backend,
|
||||||
authMechanism: this.authMechanism,
|
authMechanism: this.authMechanism,
|
||||||
backendOptions: this.backendOptions
|
backendOptions: this.backendOptions,
|
||||||
|
testOnly: true
|
||||||
};
|
};
|
||||||
if (this.id) {
|
if (this.id) {
|
||||||
data.id = this.id;
|
data.id = this.id;
|
||||||
|
@ -332,6 +333,7 @@ StorageConfig.prototype = {
|
||||||
$.ajax({
|
$.ajax({
|
||||||
type: 'GET',
|
type: 'GET',
|
||||||
url: OC.generateUrl(this._url + '/{id}', {id: this.id}),
|
url: OC.generateUrl(this._url + '/{id}', {id: this.id}),
|
||||||
|
data: {'testOnly': true},
|
||||||
success: options.success,
|
success: options.success,
|
||||||
error: options.error
|
error: options.error
|
||||||
});
|
});
|
||||||
|
@ -911,6 +913,7 @@ MountConfigListView.prototype = _.extend({
|
||||||
$.ajax({
|
$.ajax({
|
||||||
type: 'GET',
|
type: 'GET',
|
||||||
url: OC.generateUrl('apps/files_external/userglobalstorages'),
|
url: OC.generateUrl('apps/files_external/userglobalstorages'),
|
||||||
|
data: {'testOnly': true},
|
||||||
contentType: 'application/json',
|
contentType: 'application/json',
|
||||||
success: function(result) {
|
success: function(result) {
|
||||||
var onCompletion = jQuery.Deferred();
|
var onCompletion = jQuery.Deferred();
|
||||||
|
|
|
@ -78,6 +78,7 @@ OCA.External.StatusManager = {
|
||||||
defObj = $.ajax({
|
defObj = $.ajax({
|
||||||
type: 'GET',
|
type: 'GET',
|
||||||
url: OC.webroot + '/index.php/apps/files_external/' + ((mountData.type === 'personal') ? 'userstorages' : 'userglobalstorages') + '/' + mountData.id,
|
url: OC.webroot + '/index.php/apps/files_external/' + ((mountData.type === 'personal') ? 'userstorages' : 'userglobalstorages') + '/' + mountData.id,
|
||||||
|
data: {'testOnly': false},
|
||||||
success: function (response) {
|
success: function (response) {
|
||||||
if (response && response.status === 0) {
|
if (response && response.status === 0) {
|
||||||
self.mountStatus[mountData.mount_point] = response;
|
self.mountStatus[mountData.mount_point] = response;
|
||||||
|
|
|
@ -215,7 +215,7 @@ class OC_Mount_Config {
|
||||||
* @return int see self::STATUS_*
|
* @return int see self::STATUS_*
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public static function getBackendStatus($class, $options, $isPersonal) {
|
public static function getBackendStatus($class, $options, $isPersonal, $testOnly = true) {
|
||||||
if (self::$skipTest) {
|
if (self::$skipTest) {
|
||||||
return StorageNotAvailableException::STATUS_SUCCESS;
|
return StorageNotAvailableException::STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -228,7 +228,7 @@ class OC_Mount_Config {
|
||||||
$storage = new $class($options);
|
$storage = new $class($options);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$result = $storage->test($isPersonal);
|
$result = $storage->test($isPersonal, $testOnly);
|
||||||
$storage->setAvailability($result);
|
$storage->setAvailability($result);
|
||||||
if ($result) {
|
if ($result) {
|
||||||
return StorageNotAvailableException::STATUS_SUCCESS;
|
return StorageNotAvailableException::STATUS_SUCCESS;
|
||||||
|
|
|
@ -223,7 +223,8 @@ describe('OCA.External.Settings tests', function() {
|
||||||
applicableGroups: [],
|
applicableGroups: [],
|
||||||
mountOptions: {
|
mountOptions: {
|
||||||
'previews': true
|
'previews': true
|
||||||
}
|
},
|
||||||
|
testOnly: true
|
||||||
});
|
});
|
||||||
|
|
||||||
// TODO: respond and check data-id
|
// TODO: respond and check data-id
|
||||||
|
|
|
@ -111,7 +111,8 @@ class Application extends App {
|
||||||
/** @var \OCP\IServerContainer $server */
|
/** @var \OCP\IServerContainer $server */
|
||||||
$server = $c->query('ServerContainer');
|
$server = $c->query('ServerContainer');
|
||||||
return new MountProvider(
|
return new MountProvider(
|
||||||
$server->getConfig()
|
$server->getConfig(),
|
||||||
|
$server->getLogger()
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,7 @@ use OC\User\NoUserException;
|
||||||
use OCP\Files\Config\IMountProvider;
|
use OCP\Files\Config\IMountProvider;
|
||||||
use OCP\Files\Storage\IStorageFactory;
|
use OCP\Files\Storage\IStorageFactory;
|
||||||
use OCP\IConfig;
|
use OCP\IConfig;
|
||||||
|
use OCP\ILogger;
|
||||||
use OCP\IUser;
|
use OCP\IUser;
|
||||||
|
|
||||||
class MountProvider implements IMountProvider {
|
class MountProvider implements IMountProvider {
|
||||||
|
@ -36,10 +37,17 @@ class MountProvider implements IMountProvider {
|
||||||
protected $config;
|
protected $config;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param \OCP\IConfig $config
|
* @var ILogger
|
||||||
*/
|
*/
|
||||||
public function __construct(IConfig $config) {
|
protected $logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \OCP\IConfig $config
|
||||||
|
* @param ILogger $logger
|
||||||
|
*/
|
||||||
|
public function __construct(IConfig $config, ILogger $logger) {
|
||||||
$this->config = $config;
|
$this->config = $config;
|
||||||
|
$this->logger = $logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -55,19 +63,25 @@ class MountProvider implements IMountProvider {
|
||||||
$shares = array_filter($shares, function ($share) {
|
$shares = array_filter($shares, function ($share) {
|
||||||
return $share['permissions'] > 0;
|
return $share['permissions'] > 0;
|
||||||
});
|
});
|
||||||
$shares = array_map(function ($share) use ($user, $storageFactory) {
|
$mounts = [];
|
||||||
|
foreach ($shares as $share) {
|
||||||
return new SharedMount(
|
try {
|
||||||
|
$mounts[] = new SharedMount(
|
||||||
'\OC\Files\Storage\Shared',
|
'\OC\Files\Storage\Shared',
|
||||||
'/' . $user->getUID() . '/' . $share['file_target'],
|
$mounts,
|
||||||
array(
|
[
|
||||||
'share' => $share,
|
'share' => $share,
|
||||||
'user' => $user->getUID()
|
'user' => $user->getUID()
|
||||||
),
|
],
|
||||||
$storageFactory
|
$storageFactory
|
||||||
);
|
);
|
||||||
}, $shares);
|
} catch (\Exception $e) {
|
||||||
|
$this->logger->logException($e);
|
||||||
|
$this->logger->error('Error while trying to create shared mount');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// array_filter removes the null values from the array
|
// array_filter removes the null values from the array
|
||||||
return array_filter($shares);
|
return array_filter($mounts);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
namespace OCA\Files_Sharing;
|
namespace OCA\Files_Sharing;
|
||||||
|
|
||||||
|
use OC\Files\Filesystem;
|
||||||
use OC\Files\Mount\MountPoint;
|
use OC\Files\Mount\MountPoint;
|
||||||
use OC\Files\Mount\MoveableMount;
|
use OC\Files\Mount\MoveableMount;
|
||||||
use OC\Files\View;
|
use OC\Files\View;
|
||||||
|
@ -50,14 +51,14 @@ class SharedMount extends MountPoint implements MoveableMount {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $storage
|
* @param string $storage
|
||||||
* @param string $mountpoint
|
* @param SharedMount[] $mountpoints
|
||||||
* @param array|null $arguments
|
* @param array|null $arguments
|
||||||
* @param \OCP\Files\Storage\IStorageFactory $loader
|
* @param \OCP\Files\Storage\IStorageFactory $loader
|
||||||
*/
|
*/
|
||||||
public function __construct($storage, $mountpoint, $arguments = null, $loader = null) {
|
public function __construct($storage, array $mountpoints, $arguments = null, $loader = null) {
|
||||||
$this->user = $arguments['user'];
|
$this->user = $arguments['user'];
|
||||||
$this->recipientView = new View('/' . $this->user . '/files');
|
$this->recipientView = new View('/' . $this->user . '/files');
|
||||||
$newMountPoint = $this->verifyMountPoint($arguments['share']);
|
$newMountPoint = $this->verifyMountPoint($arguments['share'], $mountpoints);
|
||||||
$absMountPoint = '/' . $this->user . '/files' . $newMountPoint;
|
$absMountPoint = '/' . $this->user . '/files' . $newMountPoint;
|
||||||
$arguments['ownerView'] = new View('/' . $arguments['share']['uid_owner'] . '/files');
|
$arguments['ownerView'] = new View('/' . $arguments['share']['uid_owner'] . '/files');
|
||||||
parent::__construct($storage, $absMountPoint, $arguments, $loader);
|
parent::__construct($storage, $absMountPoint, $arguments, $loader);
|
||||||
|
@ -67,9 +68,10 @@ class SharedMount extends MountPoint implements MoveableMount {
|
||||||
* check if the parent folder exists otherwise move the mount point up
|
* check if the parent folder exists otherwise move the mount point up
|
||||||
*
|
*
|
||||||
* @param array $share
|
* @param array $share
|
||||||
|
* @param SharedMount[] $mountpoints
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
private function verifyMountPoint(&$share) {
|
private function verifyMountPoint(&$share, array $mountpoints) {
|
||||||
|
|
||||||
$mountPoint = basename($share['file_target']);
|
$mountPoint = basename($share['file_target']);
|
||||||
$parent = dirname($share['file_target']);
|
$parent = dirname($share['file_target']);
|
||||||
|
@ -78,10 +80,10 @@ class SharedMount extends MountPoint implements MoveableMount {
|
||||||
$parent = Helper::getShareFolder($this->recipientView);
|
$parent = Helper::getShareFolder($this->recipientView);
|
||||||
}
|
}
|
||||||
|
|
||||||
$newMountPoint = \OCA\Files_Sharing\Helper::generateUniqueTarget(
|
$newMountPoint = $this->generateUniqueTarget(
|
||||||
\OC\Files\Filesystem::normalizePath($parent . '/' . $mountPoint),
|
\OC\Files\Filesystem::normalizePath($parent . '/' . $mountPoint),
|
||||||
[],
|
$this->recipientView,
|
||||||
$this->recipientView
|
$mountpoints
|
||||||
);
|
);
|
||||||
|
|
||||||
if ($newMountPoint !== $share['file_target']) {
|
if ($newMountPoint !== $share['file_target']) {
|
||||||
|
@ -93,6 +95,37 @@ class SharedMount extends MountPoint implements MoveableMount {
|
||||||
return $newMountPoint;
|
return $newMountPoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $path
|
||||||
|
* @param View $view
|
||||||
|
* @param SharedMount[] $mountpoints
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
private function generateUniqueTarget($path, $view, array $mountpoints) {
|
||||||
|
$pathinfo = pathinfo($path);
|
||||||
|
$ext = (isset($pathinfo['extension'])) ? '.'.$pathinfo['extension'] : '';
|
||||||
|
$name = $pathinfo['filename'];
|
||||||
|
$dir = $pathinfo['dirname'];
|
||||||
|
|
||||||
|
// Helper function to find existing mount points
|
||||||
|
$mountpointExists = function($path) use ($mountpoints) {
|
||||||
|
foreach ($mountpoints as $mountpoint) {
|
||||||
|
if ($mountpoint->getShare()['file_target'] === $path) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
$i = 2;
|
||||||
|
while ($view->file_exists($path) || $mountpointExists($path)) {
|
||||||
|
$path = Filesystem::normalizePath($dir . '/' . $name . ' ('.$i.')' . $ext);
|
||||||
|
$i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $path;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* update fileTarget in the database if the mount point changed
|
* update fileTarget in the database if the mount point changed
|
||||||
*
|
*
|
||||||
|
|
|
@ -337,9 +337,16 @@ class Storage {
|
||||||
// Restore encrypted version of the old file for the newly restored file
|
// Restore encrypted version of the old file for the newly restored file
|
||||||
// This has to happen manually here since the file is manually copied below
|
// This has to happen manually here since the file is manually copied below
|
||||||
$oldVersion = $users_view->getFileInfo($fileToRestore)->getEncryptedVersion();
|
$oldVersion = $users_view->getFileInfo($fileToRestore)->getEncryptedVersion();
|
||||||
|
$oldFileInfo = $users_view->getFileInfo($fileToRestore);
|
||||||
$newFileInfo = $files_view->getFileInfo($filename);
|
$newFileInfo = $files_view->getFileInfo($filename);
|
||||||
$cache = $newFileInfo->getStorage()->getCache();
|
$cache = $newFileInfo->getStorage()->getCache();
|
||||||
$cache->update($newFileInfo->getId(), ['encrypted' => $oldVersion, 'encryptedVersion' => $oldVersion]);
|
$cache->update(
|
||||||
|
$newFileInfo->getId(), [
|
||||||
|
'encrypted' => $oldVersion,
|
||||||
|
'encryptedVersion' => $oldVersion,
|
||||||
|
'size' => $oldFileInfo->getSize()
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
// rollback
|
// rollback
|
||||||
if (self::copyFileContents($users_view, $fileToRestore, 'files' . $filename)) {
|
if (self::copyFileContents($users_view, $fileToRestore, 'files' . $filename)) {
|
||||||
|
|
|
@ -730,7 +730,14 @@ class Access extends LDAPUtility implements user\IUserTools {
|
||||||
$user->unmark();
|
$user->unmark();
|
||||||
$user = $this->userManager->get($ocName);
|
$user = $this->userManager->get($ocName);
|
||||||
}
|
}
|
||||||
|
if ($user !== null) {
|
||||||
$user->processAttributes($userRecord);
|
$user->processAttributes($userRecord);
|
||||||
|
} else {
|
||||||
|
\OC::$server->getLogger()->debug(
|
||||||
|
"The ldap user manager returned null for $ocName",
|
||||||
|
['app'=>'user_ldap']
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -566,3 +566,16 @@ Feature: sharing
|
||||||
| path | welcome.txt |
|
| path | welcome.txt |
|
||||||
| shareType | 3 |
|
| shareType | 3 |
|
||||||
Then share ids should match
|
Then share ids should match
|
||||||
|
|
||||||
|
Scenario: unique target names for incomming shares
|
||||||
|
Given user "user0" exists
|
||||||
|
And user "user1" exists
|
||||||
|
And user "user2" exists
|
||||||
|
And user "user0" created a folder "/foo"
|
||||||
|
And user "user1" created a folder "/foo"
|
||||||
|
When file "/foo" of user "user0" is shared with user "user2"
|
||||||
|
And file "/foo" of user "user1" is shared with user "user2"
|
||||||
|
Then user "user2" should see following elements
|
||||||
|
| /foo/ |
|
||||||
|
| /foo%20(2)/ |
|
||||||
|
|
||||||
|
|
|
@ -73,7 +73,7 @@ Feature: webdav-related
|
||||||
And As an "admin"
|
And As an "admin"
|
||||||
When Downloading file "/welcome.txt"
|
When Downloading file "/welcome.txt"
|
||||||
Then The following headers should be set
|
Then The following headers should be set
|
||||||
|Content-Disposition|attachment|
|
|Content-Disposition|attachment; filename*=UTF-8''welcome.txt; filename="welcome.txt"|
|
||||||
|Content-Security-Policy|default-src 'self'; script-src 'self' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; frame-src *; img-src * data: blob:; font-src 'self' data:; media-src *; connect-src *|
|
|Content-Security-Policy|default-src 'self'; script-src 'self' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; frame-src *; img-src * data: blob:; font-src 'self' data:; media-src *; connect-src *|
|
||||||
|X-Content-Type-Options |nosniff|
|
|X-Content-Type-Options |nosniff|
|
||||||
|X-Download-Options|noopen|
|
|X-Download-Options|noopen|
|
||||||
|
@ -88,7 +88,7 @@ Feature: webdav-related
|
||||||
And As an "admin"
|
And As an "admin"
|
||||||
When Downloading file "/welcome.txt"
|
When Downloading file "/welcome.txt"
|
||||||
Then The following headers should be set
|
Then The following headers should be set
|
||||||
|Content-Disposition|attachment|
|
|Content-Disposition|attachment; filename*=UTF-8''welcome.txt; filename="welcome.txt"|
|
||||||
|Content-Security-Policy|default-src 'self'; script-src 'self' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; frame-src *; img-src * data: blob:; font-src 'self' data:; media-src *; connect-src *|
|
|Content-Security-Policy|default-src 'self'; script-src 'self' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; frame-src *; img-src * data: blob:; font-src 'self' data:; media-src *; connect-src *|
|
||||||
|X-Content-Type-Options |nosniff|
|
|X-Content-Type-Options |nosniff|
|
||||||
|X-Download-Options|noopen|
|
|X-Download-Options|noopen|
|
||||||
|
|
|
@ -76,7 +76,8 @@
|
||||||
$.ajax({
|
$.ajax({
|
||||||
type: 'PROPFIND',
|
type: 'PROPFIND',
|
||||||
url: url,
|
url: url,
|
||||||
complete: afterCall
|
complete: afterCall,
|
||||||
|
allowAuthErrors: true
|
||||||
});
|
});
|
||||||
return deferred.promise();
|
return deferred.promise();
|
||||||
},
|
},
|
||||||
|
@ -209,7 +210,8 @@
|
||||||
$.ajax({
|
$.ajax({
|
||||||
type: 'GET',
|
type: 'GET',
|
||||||
url: OC.linkTo('', oc_dataURL+'/htaccesstest.txt?t=' + (new Date()).getTime()),
|
url: OC.linkTo('', oc_dataURL+'/htaccesstest.txt?t=' + (new Date()).getTime()),
|
||||||
complete: afterCall
|
complete: afterCall,
|
||||||
|
allowAuthErrors: true
|
||||||
});
|
});
|
||||||
return deferred.promise();
|
return deferred.promise();
|
||||||
},
|
},
|
||||||
|
|
|
@ -256,7 +256,7 @@ class AppManager implements IAppManager {
|
||||||
}
|
}
|
||||||
unset($this->installedAppsCache[$appId]);
|
unset($this->installedAppsCache[$appId]);
|
||||||
$this->appConfig->setValue($appId, 'enabled', 'no');
|
$this->appConfig->setValue($appId, 'enabled', 'no');
|
||||||
$this->dispatcher->dispatch(ManagerEvent::EVENT_APP_ENABLE, new ManagerEvent(
|
$this->dispatcher->dispatch(ManagerEvent::EVENT_APP_DISABLE, new ManagerEvent(
|
||||||
ManagerEvent::EVENT_APP_DISABLE, $appId
|
ManagerEvent::EVENT_APP_DISABLE, $appId
|
||||||
));
|
));
|
||||||
$this->clearAppsCache();
|
$this->clearAppsCache();
|
||||||
|
|
Loading…
Reference in New Issue