зеркало из https://github.com/nextcloud/server.git
Multiple fixes
- Fix tests - Use non deprecated event stuff - Add a bit of type hinting to the new stuff - More safe handling of instanceOfStorage (share might not be the first wrapper) - Fix resharing Signed-off-by: Carl Schwan <carl@carlschwan.eu>
This commit is contained in:
Родитель
ab1a20522b
Коммит
7b723813ce
|
@ -38,6 +38,7 @@ namespace OCA\DAV\Connector\Sabre;
|
|||
use OC\Files\Mount\MoveableMount;
|
||||
use OC\Files\Node\File;
|
||||
use OC\Files\Node\Folder;
|
||||
use OC\Files\Storage\Wrapper\Wrapper;
|
||||
use OC\Files\View;
|
||||
use OCA\DAV\Connector\Sabre\Exception\InvalidPath;
|
||||
use OCP\Files\FileInfo;
|
||||
|
@ -334,9 +335,14 @@ abstract class Node implements \Sabre\DAV\INode {
|
|||
$storage = null;
|
||||
}
|
||||
|
||||
if ($storage && $storage->instanceOfStorage('\OCA\Files_Sharing\SharedStorage')) {
|
||||
if ($storage && $storage->instanceOfStorage(\OCA\Files_Sharing\SharedStorage::class)) {
|
||||
/** @var \OCA\Files_Sharing\SharedStorage $storage */
|
||||
$attributes = $storage->getShare()->getAttributes()->toArray();
|
||||
$attributes = $storage->getShare()->getAttributes();
|
||||
if ($attributes === null) {
|
||||
return [];
|
||||
} else {
|
||||
return $attributes->toArray();
|
||||
}
|
||||
}
|
||||
|
||||
return $attributes;
|
||||
|
|
|
@ -36,6 +36,7 @@ use OCP\AppFramework\OCSController;
|
|||
use OCP\AppFramework\Utility\ITimeFactory;
|
||||
use OCP\EventDispatcher\GenericEvent;
|
||||
use OCP\EventDispatcher\IEventDispatcher;
|
||||
use OCP\Files\Events\BeforeDirectFileDownloadEvent;
|
||||
use OCP\Files\File;
|
||||
use OCP\Files\IRootFolder;
|
||||
use OCP\IRequest;
|
||||
|
@ -106,10 +107,10 @@ class DirectController extends OCSController {
|
|||
throw new OCSBadRequestException('Direct download only works for files');
|
||||
}
|
||||
|
||||
$event = new GenericEvent(null, ['path' => $userFolder->getRelativePath($file->getPath())]);
|
||||
$this->eventDispatcher->dispatch('file.beforeGetDirect', $event);
|
||||
$event = new BeforeDirectFileDownloadEvent($userFolder->getRelativePath($file->getPath()));
|
||||
$this->eventDispatcher->dispatchTyped($event);
|
||||
|
||||
if ($event->getArgument('run') === false) {
|
||||
if ($event->isSuccessful() === false) {
|
||||
throw new OCSForbiddenException('Permission denied to download file');
|
||||
}
|
||||
|
||||
|
|
|
@ -37,18 +37,11 @@ use Sabre\DAV\Exception\NotFound;
|
|||
*/
|
||||
class ViewOnlyPlugin extends ServerPlugin {
|
||||
|
||||
/** @var Server $server */
|
||||
private $server;
|
||||
private ?Server $server = null;
|
||||
private LoggerInterface $logger;
|
||||
|
||||
/** @var LoggerInterface $logger */
|
||||
private $logger;
|
||||
|
||||
/**
|
||||
* @param LoggerInterface $logger
|
||||
*/
|
||||
public function __construct(LoggerInterface $logger) {
|
||||
$this->logger = $logger;
|
||||
$this->server = null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -58,11 +51,8 @@ class ViewOnlyPlugin extends ServerPlugin {
|
|||
* addPlugin is called.
|
||||
*
|
||||
* This method should set up the required event subscriptions.
|
||||
*
|
||||
* @param Server $server
|
||||
* @return void
|
||||
*/
|
||||
public function initialize(Server $server) {
|
||||
public function initialize(Server $server): void {
|
||||
$this->server = $server;
|
||||
//priority 90 to make sure the plugin is called before
|
||||
//Sabre\DAV\CorePlugin::httpGet
|
||||
|
@ -73,17 +63,14 @@ class ViewOnlyPlugin extends ServerPlugin {
|
|||
* Disallow download via DAV Api in case file being received share
|
||||
* and having special permission
|
||||
*
|
||||
* @param RequestInterface $request request object
|
||||
* @return boolean
|
||||
* @throws Forbidden
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
public function checkViewOnly(
|
||||
RequestInterface $request
|
||||
) {
|
||||
public function checkViewOnly(RequestInterface $request): bool {
|
||||
$path = $request->getPath();
|
||||
|
||||
try {
|
||||
assert($this->server !== null);
|
||||
$davNode = $this->server->tree->getNodeForPath($path);
|
||||
if (!($davNode instanceof DavFile)) {
|
||||
return true;
|
||||
|
@ -92,21 +79,28 @@ class ViewOnlyPlugin extends ServerPlugin {
|
|||
$node = $davNode->getNode();
|
||||
|
||||
$storage = $node->getStorage();
|
||||
// using string as we have no guarantee that "files_sharing" app is loaded
|
||||
if (!$storage->instanceOfStorage('OCA\Files_Sharing\SharedStorage')) {
|
||||
|
||||
if (!$storage->instanceOfStorage(\OCA\Files_Sharing\SharedStorage::class)) {
|
||||
return true;
|
||||
}
|
||||
// Extract extra permissions
|
||||
/** @var \OCA\Files_Sharing\SharedStorage $storage */
|
||||
$share = $storage->getShare();
|
||||
|
||||
$attributes = $share->getAttributes();
|
||||
if ($attributes === null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check if read-only and on whether permission can download is both set and disabled.
|
||||
$canDownload = $share->getAttributes()->getAttribute('permissions', 'download');
|
||||
$canDownload = $attributes->getAttribute('permissions', 'download');
|
||||
if ($canDownload !== null && !$canDownload) {
|
||||
throw new Forbidden('Access to this resource has been denied because it is in view-only mode.');
|
||||
}
|
||||
} catch (NotFound $e) {
|
||||
$this->logger->warning($e->getMessage());
|
||||
$this->logger->warning($e->getMessage(), [
|
||||
'exception' => $e,
|
||||
]);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
@ -34,11 +34,12 @@ use OCP\AppFramework\Http\DataResponse;
|
|||
use OCP\AppFramework\OCS\OCSBadRequestException;
|
||||
use OCP\AppFramework\OCS\OCSNotFoundException;
|
||||
use OCP\AppFramework\Utility\ITimeFactory;
|
||||
use OCP\EventDispatcher\IEventDispatcher;
|
||||
use OCP\Files\File;
|
||||
use OCP\Files\Folder;
|
||||
use OCP\Files\IRootFolder;
|
||||
use OCP\IRequest;
|
||||
use OCP\IURLGenerator;
|
||||
use OCP\IUrlGenerator;
|
||||
use OCP\Security\ISecureRandom;
|
||||
use Test\TestCase;
|
||||
|
||||
|
@ -56,11 +57,13 @@ class DirectControllerTest extends TestCase {
|
|||
/** @var ITimeFactory|\PHPUnit\Framework\MockObject\MockObject */
|
||||
private $timeFactory;
|
||||
|
||||
/** @var IURLGenerator|\PHPUnit\Framework\MockObject\MockObject */
|
||||
/** @var IUrlGenerator|\PHPUnit\Framework\MockObject\MockObject */
|
||||
private $urlGenerator;
|
||||
|
||||
/** @var DirectController */
|
||||
private $controller;
|
||||
/** @var IEventDispatcher|\PHPUnit\Framework\MockObject\MockObject */
|
||||
private $eventDispatcher;
|
||||
|
||||
private DirectController $controller;
|
||||
|
||||
protected function setUp(): void {
|
||||
parent::setUp();
|
||||
|
@ -69,7 +72,8 @@ class DirectControllerTest extends TestCase {
|
|||
$this->directMapper = $this->createMock(DirectMapper::class);
|
||||
$this->random = $this->createMock(ISecureRandom::class);
|
||||
$this->timeFactory = $this->createMock(ITimeFactory::class);
|
||||
$this->urlGenerator = $this->createMock(IURLGenerator::class);
|
||||
$this->urlGenerator = $this->createMock(IUrlGenerator::class);
|
||||
$this->eventDispatcher = $this->createMock(IEventDispatcher::class);
|
||||
|
||||
$this->controller = new DirectController(
|
||||
'dav',
|
||||
|
@ -79,11 +83,12 @@ class DirectControllerTest extends TestCase {
|
|||
$this->directMapper,
|
||||
$this->random,
|
||||
$this->timeFactory,
|
||||
$this->urlGenerator
|
||||
$this->urlGenerator,
|
||||
$this->eventDispatcher
|
||||
);
|
||||
}
|
||||
|
||||
public function testGetUrlNonExistingFileId() {
|
||||
public function testGetUrlNonExistingFileId(): void {
|
||||
$userFolder = $this->createMock(Folder::class);
|
||||
$this->rootFolder->method('getUserFolder')
|
||||
->with('awesomeUser')
|
||||
|
@ -97,7 +102,7 @@ class DirectControllerTest extends TestCase {
|
|||
$this->controller->getUrl(101);
|
||||
}
|
||||
|
||||
public function testGetUrlForFolder() {
|
||||
public function testGetUrlForFolder(): void {
|
||||
$userFolder = $this->createMock(Folder::class);
|
||||
$this->rootFolder->method('getUserFolder')
|
||||
->with('awesomeUser')
|
||||
|
@ -113,7 +118,7 @@ class DirectControllerTest extends TestCase {
|
|||
$this->controller->getUrl(101);
|
||||
}
|
||||
|
||||
public function testGetUrlValid() {
|
||||
public function testGetUrlValid(): void {
|
||||
$userFolder = $this->createMock(Folder::class);
|
||||
$this->rootFolder->method('getUserFolder')
|
||||
->with('awesomeUser')
|
||||
|
@ -128,6 +133,9 @@ class DirectControllerTest extends TestCase {
|
|||
->with(101)
|
||||
->willReturn([$file]);
|
||||
|
||||
$userFolder->method('getRelativePath')
|
||||
->willReturn('/path');
|
||||
|
||||
$this->random->method('generate')
|
||||
->with(
|
||||
60,
|
||||
|
|
|
@ -36,8 +36,7 @@ use OCA\DAV\Connector\Sabre\Exception\Forbidden;
|
|||
|
||||
class ViewOnlyPluginTest extends TestCase {
|
||||
|
||||
/** @var ViewOnlyPlugin */
|
||||
private $plugin;
|
||||
private ViewOnlyPlugin $plugin;
|
||||
/** @var Tree | \PHPUnit\Framework\MockObject\MockObject */
|
||||
private $tree;
|
||||
/** @var RequestInterface | \PHPUnit\Framework\MockObject\MockObject */
|
||||
|
@ -56,14 +55,14 @@ class ViewOnlyPluginTest extends TestCase {
|
|||
$this->plugin->initialize($server);
|
||||
}
|
||||
|
||||
public function testCanGetNonDav() {
|
||||
public function testCanGetNonDav(): void {
|
||||
$this->request->expects($this->once())->method('getPath')->willReturn('files/test/target');
|
||||
$this->tree->method('getNodeForPath')->willReturn(null);
|
||||
|
||||
$this->assertTrue($this->plugin->checkViewOnly($this->request));
|
||||
}
|
||||
|
||||
public function testCanGetNonShared() {
|
||||
public function testCanGetNonShared(): void {
|
||||
$this->request->expects($this->once())->method('getPath')->willReturn('files/test/target');
|
||||
$davNode = $this->createMock(DavFile::class);
|
||||
$this->tree->method('getNodeForPath')->willReturn($davNode);
|
||||
|
@ -78,7 +77,7 @@ class ViewOnlyPluginTest extends TestCase {
|
|||
$this->assertTrue($this->plugin->checkViewOnly($this->request));
|
||||
}
|
||||
|
||||
public function providesDataForCanGet() {
|
||||
public function providesDataForCanGet(): array {
|
||||
return [
|
||||
// has attribute permissions-download enabled - can get file
|
||||
[ $this->createMock(File::class), true, true],
|
||||
|
@ -92,7 +91,7 @@ class ViewOnlyPluginTest extends TestCase {
|
|||
/**
|
||||
* @dataProvider providesDataForCanGet
|
||||
*/
|
||||
public function testCanGet($nodeInfo, $attrEnabled, $expectCanDownloadFile) {
|
||||
public function testCanGet(File $nodeInfo, ?bool $attrEnabled, bool $expectCanDownloadFile): void {
|
||||
$this->request->expects($this->once())->method('getPath')->willReturn('files/test/target');
|
||||
|
||||
$davNode = $this->createMock(DavFile::class);
|
||||
|
|
|
@ -50,6 +50,7 @@ use OCA\Files_Sharing\Notification\Listener;
|
|||
use OCA\Files_Sharing\Notification\Notifier;
|
||||
use OCA\Files\Event\LoadAdditionalScriptsEvent;
|
||||
use OCA\Files\Event\LoadSidebar;
|
||||
use OCP\Files\Event\BeforeDirectGetEvent;
|
||||
use OCA\Files_Sharing\ShareBackend\File;
|
||||
use OCA\Files_Sharing\ShareBackend\Folder;
|
||||
use OCA\Files_Sharing\ViewOnly;
|
||||
|
@ -62,6 +63,8 @@ use OCP\EventDispatcher\IEventDispatcher;
|
|||
use OCP\EventDispatcher\GenericEvent;
|
||||
use OCP\Federation\ICloudIdManager;
|
||||
use OCP\Files\Config\IMountProviderCollection;
|
||||
use OCP\Files\Events\BeforeDirectFileDownloadEvent;
|
||||
use OCP\Files\Events\BeforeZipCreatedEvent;
|
||||
use OCP\Files\IRootFolder;
|
||||
use OCP\Group\Events\UserAddedEvent;
|
||||
use OCP\IDBConnection;
|
||||
|
@ -157,59 +160,53 @@ class Application extends App implements IBootstrap {
|
|||
|
||||
public function registerDownloadEvents(
|
||||
IEventDispatcher $dispatcher,
|
||||
?IUserSession $userSession,
|
||||
IUserSession $userSession,
|
||||
IRootFolder $rootFolder
|
||||
): void {
|
||||
|
||||
$dispatcher->addListener(
|
||||
'file.beforeGetDirect',
|
||||
function (GenericEvent $event) use ($userSession, $rootFolder) {
|
||||
$pathsToCheck = [$event->getArgument('path')];
|
||||
$event->setArgument('run', true);
|
||||
|
||||
BeforeDirectFileDownloadEvent::class,
|
||||
function (BeforeDirectFileDownloadEvent $event) use ($userSession, $rootFolder): void {
|
||||
$pathsToCheck = [$event->getPath()];
|
||||
// Check only for user/group shares. Don't restrict e.g. share links
|
||||
if ($userSession && $userSession->isLoggedIn()) {
|
||||
$uid = $userSession->getUser()->getUID();
|
||||
$user = $userSession->getUser();
|
||||
if ($user) {
|
||||
$viewOnlyHandler = new ViewOnly(
|
||||
$rootFolder->getUserFolder($uid)
|
||||
$rootFolder->getUserFolder($user->getUID())
|
||||
);
|
||||
if (!$viewOnlyHandler->check($pathsToCheck)) {
|
||||
$event->setArgument('run', false);
|
||||
$event->setArgument('errorMessage', 'Access to this resource or one of its sub-items has been denied.');
|
||||
$event->setSuccessful(false);
|
||||
$event->setErrorMessage('Access to this resource or one of its sub-items has been denied.');
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
$dispatcher->addListener(
|
||||
'file.beforeCreateZip',
|
||||
function (GenericEvent $event) use ($userSession, $rootFolder) {
|
||||
$dir = $event->getArgument('dir');
|
||||
$files = $event->getArgument('files');
|
||||
BeforeZipCreatedEvent::class,
|
||||
function (BeforeZipCreatedEvent $event) use ($userSession, $rootFolder): void {
|
||||
$dir = $event->getDirectory();
|
||||
$files = $event->getFiles();
|
||||
|
||||
$pathsToCheck = [];
|
||||
if (\is_array($files)) {
|
||||
foreach ($files as $file) {
|
||||
$pathsToCheck[] = $dir . '/' . $file;
|
||||
}
|
||||
} elseif (\is_string($files)) {
|
||||
$pathsToCheck[] = $dir . '/' . $files;
|
||||
foreach ($files as $file) {
|
||||
$pathsToCheck[] = $dir . '/' . $file;
|
||||
}
|
||||
|
||||
// Check only for user/group shares. Don't restrict e.g. share links
|
||||
if ($userSession && $userSession->isLoggedIn()) {
|
||||
$uid = $userSession->getUser()->getUID();
|
||||
$user = $userSession->getUser();
|
||||
if ($user) {
|
||||
$viewOnlyHandler = new ViewOnly(
|
||||
$rootFolder->getUserFolder($uid)
|
||||
$rootFolder->getUserFolder($user->getUID())
|
||||
);
|
||||
if (!$viewOnlyHandler->check($pathsToCheck)) {
|
||||
$event->setArgument('errorMessage', 'Access to this resource or one of its sub-items has been denied.');
|
||||
$event->setArgument('run', false);
|
||||
$event->setErrorMessage('Access to this resource or one of its sub-items has been denied.');
|
||||
$event->setSuccessful(false);
|
||||
} else {
|
||||
$event->setArgument('run', true);
|
||||
$event->setSuccessful(true);
|
||||
}
|
||||
} else {
|
||||
$event->setArgument('run', true);
|
||||
$event->setSuccessful(true);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
|
|
@ -136,7 +136,7 @@ class PublicPreviewController extends PublicShareController {
|
|||
* @param $token
|
||||
* @return DataResponse|FileDisplayResponse
|
||||
*/
|
||||
public function directLink($token) {
|
||||
public function directLink(string $token) {
|
||||
// No token no image
|
||||
if ($token === '') {
|
||||
return new DataResponse([], Http::STATUS_BAD_REQUEST);
|
||||
|
|
|
@ -45,6 +45,7 @@ declare(strict_types=1);
|
|||
namespace OCA\Files_Sharing\Controller;
|
||||
|
||||
use OC\Files\FileInfo;
|
||||
use OC\Files\Storage\Wrapper\Wrapper;
|
||||
use OCA\Files_Sharing\Exceptions\SharingRightsException;
|
||||
use OCA\Files_Sharing\External\Storage;
|
||||
use OCA\Files_Sharing\SharedStorage;
|
||||
|
@ -524,14 +525,7 @@ class ShareAPIController extends OCSController {
|
|||
$permissions &= ~($permissions & ~$node->getPermissions());
|
||||
}
|
||||
|
||||
if ($share->getNode()->getStorage()->instanceOfStorage(SharedStorage::class)) {
|
||||
/** @var \OCA\Files_Sharing\SharedStorage $storage */
|
||||
$inheritedAttributes = $share->getNode()->getStorage()->getShare()->getAttributes();
|
||||
if ($inheritedAttributes !== null && $inheritedAttributes->getAttribute('permissions', 'download') === false) {
|
||||
$share->setHideDownload(true);
|
||||
}
|
||||
}
|
||||
|
||||
$this->checkInheritedAttributes($share);
|
||||
|
||||
if ($shareType === IShare::TYPE_USER) {
|
||||
// Valid user is required to share
|
||||
|
@ -1110,6 +1104,25 @@ class ShareAPIController extends OCSController {
|
|||
$share->setNote($note);
|
||||
}
|
||||
|
||||
$userFolder = $this->rootFolder->getUserFolder($this->currentUser);
|
||||
|
||||
// get the node with the point of view of the current user
|
||||
$nodes = $userFolder->getById($share->getNode()->getId());
|
||||
if (count($nodes) > 0) {
|
||||
$node = $nodes[0];
|
||||
$storage = $node->getStorage();
|
||||
if ($storage && $storage->instanceOfStorage(SharedStorage::class)) {
|
||||
/** @var \OCA\Files_Sharing\SharedStorage $storage */
|
||||
$inheritedAttributes = $storage->getShare()->getAttributes();
|
||||
if ($inheritedAttributes !== null && $inheritedAttributes->getAttribute('permissions', 'download') === false) {
|
||||
if ($hideDownload === 'false') {
|
||||
throw new OCSBadRequestException($this->l->t('Cannot increase permissions'));
|
||||
}
|
||||
$share->setHideDownload(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* expirationdate, password and publicUpload only make sense for link shares
|
||||
*/
|
||||
|
@ -1135,24 +1148,6 @@ class ShareAPIController extends OCSController {
|
|||
$share->setHideDownload(false);
|
||||
}
|
||||
|
||||
$userFolder = $this->rootFolder->getUserFolder($this->currentUser);
|
||||
// get the node with the point of view of the current user
|
||||
$nodes = $userFolder->getById($share->getNode()->getId());
|
||||
if (count($nodes) > 0) {
|
||||
$node = $nodes[0];
|
||||
$storage = $node->getStorage();
|
||||
if ($storage->instanceOfStorage(SharedStorage::class)) {
|
||||
/** @var \OCA\Files_Sharing\SharedStorage $storage */
|
||||
$inheritedAttributes = $storage->getShare()->getAttributes();
|
||||
if ($inheritedAttributes !== null && $inheritedAttributes->getAttribute('permissions', 'download') === false) {
|
||||
if ($hideDownload === 'false') {
|
||||
throw new OCSBadRequestException($this->l->t('Cannot increate permissions'));
|
||||
}
|
||||
$share->setHideDownload(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$newPermissions = null;
|
||||
if ($publicUpload === 'true') {
|
||||
$newPermissions = Constants::PERMISSION_READ | Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE | Constants::PERMISSION_DELETE;
|
||||
|
@ -1905,4 +1900,24 @@ class ShareAPIController extends OCSController {
|
|||
|
||||
return $share;
|
||||
}
|
||||
|
||||
private function checkInheritedAttributes(IShare $share): void {
|
||||
if ($share->getNode()->getStorage()->instanceOfStorage(SharedStorage::class)) {
|
||||
$storage = $share->getNode()->getStorage();
|
||||
if ($storage instanceof Wrapper) {
|
||||
$storage = $storage->getInstanceOfStorage(SharedStorage::class);
|
||||
if ($storage === null) {
|
||||
throw new \RuntimeException('Should not happen, instanceOfStorage but getInstanceOfStorage return null');
|
||||
}
|
||||
} else {
|
||||
throw new \RuntimeException('Should not happen, instanceOfStorage but not a wrapper');
|
||||
}
|
||||
/** @var \OCA\Files_Sharing\SharedStorage $storage */
|
||||
$inheritedAttributes = $storage->getShare()->getAttributes();
|
||||
if ($inheritedAttributes !== null && $inheritedAttributes->getAttribute('permissions', 'download') === false) {
|
||||
$share->setHideDownload(true);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -242,8 +242,9 @@ class MountProvider implements IMountProvider {
|
|||
$superPermissions |= $share->getPermissions();
|
||||
|
||||
// update share permission attributes
|
||||
if ($share->getAttributes() !== null) {
|
||||
foreach ($share->getAttributes()->toArray() as $attribute) {
|
||||
$attributes = $share->getAttributes();
|
||||
if ($attributes !== null) {
|
||||
foreach ($attributes->toArray() as $attribute) {
|
||||
if ($superAttributes->getAttribute($attribute['scope'], $attribute['key']) === true) {
|
||||
// if super share attribute is already enabled, it is most permissive
|
||||
continue;
|
||||
|
|
|
@ -80,8 +80,9 @@
|
|||
|
||||
<ActionCheckbox ref="canDownload"
|
||||
:checked.sync="canDownload"
|
||||
v-if="isSetDownloadButtonVisible"
|
||||
:disabled="saving || !canSetDownload">
|
||||
{{ t('files_sharing', 'Allow download') }}
|
||||
{{ allowDownloadText }}
|
||||
</ActionCheckbox>
|
||||
|
||||
<!-- expiration date -->
|
||||
|
@ -407,6 +408,36 @@ export default {
|
|||
return (typeof this.share.status === 'object' && !Array.isArray(this.share.status))
|
||||
},
|
||||
|
||||
/**
|
||||
* @return {string}
|
||||
*/
|
||||
allowDownloadText() {
|
||||
if (this.isFolder) {
|
||||
return t('files_sharing', 'Allow download of office files')
|
||||
} else {
|
||||
return t('files_sharing', 'Allow download')
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* @return {boolean}
|
||||
*/
|
||||
isSetDownloadButtonVisible() {
|
||||
const allowedMimetypes = [
|
||||
// Office documents
|
||||
'application/msword',
|
||||
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
||||
'application/vnd.ms-powerpoint',
|
||||
'application/vnd.openxmlformats-officedocument.presentationml.presentation',
|
||||
'application/vnd.ms-excel',
|
||||
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
||||
'application/vnd.oasis.opendocument.text',
|
||||
'application/vnd.oasis.opendocument.spreadsheet',
|
||||
'application/vnd.oasis.opendocument.presentation',
|
||||
]
|
||||
|
||||
return this.isFolder || allowedMimetypes.includes(this.fileInfo.mimetype)
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
|
|
@ -159,7 +159,7 @@
|
|||
<ActionSeparator />
|
||||
|
||||
<ActionCheckbox :checked.sync="share.hideDownload"
|
||||
:disabled="saving"
|
||||
:disabled="saving || canChangeHideDownload"
|
||||
@change="queueUpdate('hideDownload')">
|
||||
{{ t('files_sharing', 'Hide download') }}
|
||||
</ActionCheckbox>
|
||||
|
@ -607,6 +607,12 @@ export default {
|
|||
isPasswordPolicyEnabled() {
|
||||
return typeof this.config.passwordPolicy === 'object'
|
||||
},
|
||||
|
||||
canChangeHideDownload() {
|
||||
const hasDisabledDownload = (shareAttribute) => shareAttribute.key === 'download' && shareAttribute.scope === 'permissions' && shareAttribute.enabled === false
|
||||
|
||||
return this.fileInfo.shareAttributes.some(hasDisabledDownload)
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
@ -868,7 +874,6 @@ export default {
|
|||
this.$emit('remove:share', this.share)
|
||||
},
|
||||
},
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
|
@ -22,6 +22,8 @@
|
|||
*/
|
||||
namespace OCA\Files_Sharing\Tests;
|
||||
|
||||
use OCP\Files\Events\BeforeDirectFileDownloadEvent;
|
||||
use OCP\Files\Events\BeforeZipCreatedEvent;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use OC\Share20\LegacyHooks;
|
||||
use OC\Share20\Manager;
|
||||
|
@ -32,6 +34,7 @@ use OCP\Constants;
|
|||
use OCP\EventDispatcher\GenericEvent;
|
||||
use OCP\EventDispatcher\IEventDispatcher;
|
||||
use OCP\Files\Cache\ICacheEntry;
|
||||
use OCP\Files\Event\BeforeDirectGetEvent;
|
||||
use OCP\Files\File;
|
||||
use OCP\Files\Folder;
|
||||
use OCP\Files\IRootFolder;
|
||||
|
@ -45,12 +48,8 @@ use Symfony\Component\EventDispatcher\EventDispatcher as SymfonyDispatcher;
|
|||
use Test\TestCase;
|
||||
|
||||
class ApplicationTest extends TestCase {
|
||||
|
||||
/** @var Application */
|
||||
private $application;
|
||||
|
||||
/** @var IEventDispatcher */
|
||||
private $eventDispatcher;
|
||||
private Application $application;
|
||||
private IEventDispatcher $eventDispatcher;
|
||||
|
||||
/** @var IUserSession */
|
||||
private $userSession;
|
||||
|
@ -81,7 +80,7 @@ class ApplicationTest extends TestCase {
|
|||
);
|
||||
}
|
||||
|
||||
public function providesDataForCanGet() {
|
||||
public function providesDataForCanGet(): array {
|
||||
// normal file (sender) - can download directly
|
||||
$senderFileStorage = $this->createMock(IStorage::class);
|
||||
$senderFileStorage->method('instanceOfStorage')->with(SharedStorage::class)->willReturn(false);
|
||||
|
@ -130,7 +129,7 @@ class ApplicationTest extends TestCase {
|
|||
/**
|
||||
* @dataProvider providesDataForCanGet
|
||||
*/
|
||||
public function testCheckDirectCanBeDownloaded($path, $userFolder, $run) {
|
||||
public function testCheckDirectCanBeDownloaded(string $path, Folder $userFolder, bool $run): void {
|
||||
$user = $this->createMock(IUser::class);
|
||||
$user->method('getUID')->willReturn('test');
|
||||
$this->userSession->method('getUser')->willReturn($user);
|
||||
|
@ -138,13 +137,13 @@ class ApplicationTest extends TestCase {
|
|||
$this->rootFolder->method('getUserFolder')->willReturn($userFolder);
|
||||
|
||||
// Simulate direct download of file
|
||||
$event = new GenericEvent(null, [ 'path' => $path ]);
|
||||
$this->eventDispatcher->dispatch('file.beforeGetDirect', $event);
|
||||
$event = new BeforeDirectFileDownloadEvent($path);
|
||||
$this->eventDispatcher->dispatchTyped($event);
|
||||
|
||||
$this->assertEquals($run, !$event->hasArgument('errorMessage'));
|
||||
$this->assertEquals($run, $event->isSuccessful());
|
||||
}
|
||||
|
||||
public function providesDataForCanZip() {
|
||||
public function providesDataForCanZip(): array {
|
||||
// Mock: Normal file/folder storage
|
||||
$nonSharedStorage = $this->createMock(IStorage::class);
|
||||
$nonSharedStorage->method('instanceOfStorage')->with(SharedStorage::class)->willReturn(false);
|
||||
|
@ -172,7 +171,7 @@ class ApplicationTest extends TestCase {
|
|||
$sender1UserFolder->method('get')->willReturn($sender1RootFolder);
|
||||
|
||||
$return[] = [ '/folder', ['bar1.txt', 'bar2.txt'], $sender1UserFolder, true ];
|
||||
$return[] = [ '/', 'folder', $sender1UserFolder, true ];
|
||||
$return[] = [ '/', ['folder'], $sender1UserFolder, true ];
|
||||
|
||||
// 3. cannot download zipped 1 non-shared file and 1 secure-shared inside non-shared folder
|
||||
$receiver1File = $this->createMock(File::class);
|
||||
|
@ -199,7 +198,7 @@ class ApplicationTest extends TestCase {
|
|||
$receiver2UserFolder = $this->createMock(Folder::class);
|
||||
$receiver2UserFolder->method('get')->willReturn($receiver2RootFolder);
|
||||
|
||||
$return[] = [ '/', 'secured-folder', $receiver2UserFolder, false ];
|
||||
$return[] = [ '/', ['secured-folder'], $receiver2UserFolder, false ];
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
@ -207,7 +206,7 @@ class ApplicationTest extends TestCase {
|
|||
/**
|
||||
* @dataProvider providesDataForCanZip
|
||||
*/
|
||||
public function testCheckZipCanBeDownloaded($dir, $files, $userFolder, $run) {
|
||||
public function testCheckZipCanBeDownloaded(string $dir, array $files, Folder $userFolder, bool $run): void {
|
||||
$user = $this->createMock(IUser::class);
|
||||
$user->method('getUID')->willReturn('test');
|
||||
$this->userSession->method('getUser')->willReturn($user);
|
||||
|
@ -216,22 +215,22 @@ class ApplicationTest extends TestCase {
|
|||
$this->rootFolder->method('getUserFolder')->with('test')->willReturn($userFolder);
|
||||
|
||||
// Simulate zip download of folder folder
|
||||
$event = new GenericEvent(null, ['dir' => $dir, 'files' => $files, 'run' => true]);
|
||||
$this->eventDispatcher->dispatch('file.beforeCreateZip', $event);
|
||||
$event = new BeforeZipCreatedEvent($dir, $files);
|
||||
$this->eventDispatcher->dispatchTyped($event);
|
||||
|
||||
$this->assertEquals($run, $event->getArgument('run'));
|
||||
$this->assertEquals($run, !$event->hasArgument('errorMessage'));
|
||||
$this->assertEquals($run, $event->isSuccessful());
|
||||
$this->assertEquals($run, $event->getErrorMessage() === null);
|
||||
}
|
||||
|
||||
public function testCheckFileUserNotFound() {
|
||||
public function testCheckFileUserNotFound(): void {
|
||||
$this->userSession->method('isLoggedIn')->willReturn(false);
|
||||
|
||||
// Simulate zip download of folder folder
|
||||
$event = new GenericEvent(null, ['dir' => '/test', 'files' => ['test.txt'], 'run' => true]);
|
||||
$this->eventDispatcher->dispatch('file.beforeCreateZip', $event);
|
||||
$event = new BeforeZipCreatedEvent('/test', ['test.txt']);
|
||||
$this->eventDispatcher->dispatchTyped($event);
|
||||
|
||||
// It should run as this would restrict e.g. share links otherwise
|
||||
$this->assertTrue($event->getArgument('run'));
|
||||
$this->assertFalse($event->hasArgument('errorMessage'));
|
||||
$this->assertTrue($event->isSuccessful());
|
||||
$this->assertEquals(null, $event->getErrorMessage());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,6 +46,7 @@ use OCP\Files\IRootFolder;
|
|||
use OCP\Files\Mount\IMountPoint;
|
||||
use OCP\Files\NotFoundException;
|
||||
use OCP\Files\Storage;
|
||||
use OCP\Files\Storage\IStorage;
|
||||
use OCP\IConfig;
|
||||
use OCP\IGroup;
|
||||
use OCP\IGroupManager;
|
||||
|
@ -1675,8 +1676,10 @@ class ShareAPIControllerTest extends TestCase {
|
|||
$path = $this->getMockBuilder(File::class)->getMock();
|
||||
$storage = $this->createMock(Storage::class);
|
||||
$storage->method('instanceOfStorage')
|
||||
->with('OCA\Files_Sharing\External\Storage')
|
||||
->willReturn(false);
|
||||
->willReturnMap([
|
||||
['OCA\Files_Sharing\External\Storage', false],
|
||||
['OCA\Files_Sharing\SharedStorage', false],
|
||||
]);
|
||||
$path->method('getStorage')->willReturn($storage);
|
||||
$userFolder->expects($this->once())
|
||||
->method('get')
|
||||
|
@ -1709,8 +1712,10 @@ class ShareAPIControllerTest extends TestCase {
|
|||
$path = $this->getMockBuilder(File::class)->getMock();
|
||||
$storage = $this->createMock(Storage::class);
|
||||
$storage->method('instanceOfStorage')
|
||||
->with('OCA\Files_Sharing\External\Storage')
|
||||
->willReturn(false);
|
||||
->willReturnMap([
|
||||
['OCA\Files_Sharing\External\Storage', false],
|
||||
['OCA\Files_Sharing\SharedStorage', false],
|
||||
]);
|
||||
$path->method('getStorage')->willReturn($storage);
|
||||
$userFolder->expects($this->once())
|
||||
->method('get')
|
||||
|
@ -1761,8 +1766,10 @@ class ShareAPIControllerTest extends TestCase {
|
|||
$path = $this->getMockBuilder(File::class)->getMock();
|
||||
$storage = $this->createMock(Storage::class);
|
||||
$storage->method('instanceOfStorage')
|
||||
->with('OCA\Files_Sharing\External\Storage')
|
||||
->willReturn(false);
|
||||
->willReturnMap([
|
||||
['OCA\Files_Sharing\External\Storage', false],
|
||||
['OCA\Files_Sharing\SharedStorage', false],
|
||||
]);
|
||||
$path->method('getStorage')->willReturn($storage);
|
||||
$userFolder->expects($this->once())
|
||||
->method('get')
|
||||
|
@ -1817,8 +1824,10 @@ class ShareAPIControllerTest extends TestCase {
|
|||
$path = $this->getMockBuilder(File::class)->getMock();
|
||||
$storage = $this->createMock(Storage::class);
|
||||
$storage->method('instanceOfStorage')
|
||||
->with('OCA\Files_Sharing\External\Storage')
|
||||
->willReturn(false);
|
||||
->willReturnMap([
|
||||
['OCA\Files_Sharing\External\Storage', false],
|
||||
['OCA\Files_Sharing\SharedStorage', false],
|
||||
]);
|
||||
$path->method('getStorage')->willReturn($storage);
|
||||
$userFolder->expects($this->once())
|
||||
->method('get')
|
||||
|
@ -1876,8 +1885,10 @@ class ShareAPIControllerTest extends TestCase {
|
|||
$path = $this->getMockBuilder(Folder::class)->getMock();
|
||||
$storage = $this->createMock(Storage::class);
|
||||
$storage->method('instanceOfStorage')
|
||||
->with('OCA\Files_Sharing\External\Storage')
|
||||
->willReturn(false);
|
||||
->willReturnMap([
|
||||
['OCA\Files_Sharing\External\Storage', false],
|
||||
['OCA\Files_Sharing\SharedStorage', false],
|
||||
]);
|
||||
$path->method('getStorage')->willReturn($storage);
|
||||
$userFolder->expects($this->once())
|
||||
->method('get')
|
||||
|
@ -1930,8 +1941,10 @@ class ShareAPIControllerTest extends TestCase {
|
|||
$path = $this->getMockBuilder(Folder::class)->getMock();
|
||||
$storage = $this->createMock(Storage::class);
|
||||
$storage->method('instanceOfStorage')
|
||||
->with('OCA\Files_Sharing\External\Storage')
|
||||
->willReturn(false);
|
||||
->willReturnMap([
|
||||
['OCA\Files_Sharing\External\Storage', false],
|
||||
['OCA\Files_Sharing\SharedStorage', false],
|
||||
]);
|
||||
$path->method('getStorage')->willReturn($storage);
|
||||
$userFolder->expects($this->once())
|
||||
->method('get')
|
||||
|
@ -1964,8 +1977,10 @@ class ShareAPIControllerTest extends TestCase {
|
|||
$path = $this->getMockBuilder(Folder::class)->getMock();
|
||||
$storage = $this->createMock(Storage::class);
|
||||
$storage->method('instanceOfStorage')
|
||||
->with('OCA\Files_Sharing\External\Storage')
|
||||
->willReturn(false);
|
||||
->willReturnMap([
|
||||
['OCA\Files_Sharing\External\Storage', false],
|
||||
['OCA\Files_Sharing\SharedStorage', false],
|
||||
]);
|
||||
$path->method('getStorage')->willReturn($storage);
|
||||
$this->rootFolder->method('getUserFolder')->with($this->currentUser)->willReturnSelf();
|
||||
$this->rootFolder->method('get')->with('valid-path')->willReturn($path);
|
||||
|
@ -1985,8 +2000,10 @@ class ShareAPIControllerTest extends TestCase {
|
|||
$path = $this->getMockBuilder(Folder::class)->getMock();
|
||||
$storage = $this->createMock(Storage::class);
|
||||
$storage->method('instanceOfStorage')
|
||||
->with('OCA\Files_Sharing\External\Storage')
|
||||
->willReturn(false);
|
||||
->willReturnMap([
|
||||
['OCA\Files_Sharing\External\Storage', false],
|
||||
['OCA\Files_Sharing\SharedStorage', false],
|
||||
]);
|
||||
$path->method('getStorage')->willReturn($storage);
|
||||
$this->rootFolder->method('getUserFolder')->with($this->currentUser)->willReturnSelf();
|
||||
$this->rootFolder->method('get')->with('valid-path')->willReturn($path);
|
||||
|
@ -2007,8 +2024,10 @@ class ShareAPIControllerTest extends TestCase {
|
|||
$path = $this->getMockBuilder(File::class)->getMock();
|
||||
$storage = $this->createMock(Storage::class);
|
||||
$storage->method('instanceOfStorage')
|
||||
->with('OCA\Files_Sharing\External\Storage')
|
||||
->willReturn(false);
|
||||
->willReturnMap([
|
||||
['OCA\Files_Sharing\External\Storage', false],
|
||||
['OCA\Files_Sharing\SharedStorage', false],
|
||||
]);
|
||||
$path->method('getStorage')->willReturn($storage);
|
||||
$this->rootFolder->method('getUserFolder')->with($this->currentUser)->willReturnSelf();
|
||||
$this->rootFolder->method('get')->with('valid-path')->willReturn($path);
|
||||
|
@ -2028,8 +2047,10 @@ class ShareAPIControllerTest extends TestCase {
|
|||
$path = $this->getMockBuilder(Folder::class)->getMock();
|
||||
$storage = $this->createMock(Storage::class);
|
||||
$storage->method('instanceOfStorage')
|
||||
->with('OCA\Files_Sharing\External\Storage')
|
||||
->willReturn(false);
|
||||
->willReturnMap([
|
||||
['OCA\Files_Sharing\External\Storage', false],
|
||||
['OCA\Files_Sharing\SharedStorage', false],
|
||||
]);
|
||||
$path->method('getStorage')->willReturn($storage);
|
||||
$this->rootFolder->method('getUserFolder')->with($this->currentUser)->willReturnSelf();
|
||||
$this->rootFolder->method('get')->with('valid-path')->willReturn($path);
|
||||
|
@ -2064,8 +2085,10 @@ class ShareAPIControllerTest extends TestCase {
|
|||
$path = $this->getMockBuilder(Folder::class)->getMock();
|
||||
$storage = $this->createMock(Storage::class);
|
||||
$storage->method('instanceOfStorage')
|
||||
->with('OCA\Files_Sharing\External\Storage')
|
||||
->willReturn(false);
|
||||
->willReturnMap([
|
||||
['OCA\Files_Sharing\External\Storage', false],
|
||||
['OCA\Files_Sharing\SharedStorage', false],
|
||||
]);
|
||||
$path->method('getStorage')->willReturn($storage);
|
||||
$this->rootFolder->method('getUserFolder')->with($this->currentUser)->willReturnSelf();
|
||||
$this->rootFolder->method('get')->with('valid-path')->willReturn($path);
|
||||
|
@ -2100,8 +2123,10 @@ class ShareAPIControllerTest extends TestCase {
|
|||
$path = $this->getMockBuilder(Folder::class)->getMock();
|
||||
$storage = $this->createMock(Storage::class);
|
||||
$storage->method('instanceOfStorage')
|
||||
->with('OCA\Files_Sharing\External\Storage')
|
||||
->willReturn(false);
|
||||
->willReturnMap([
|
||||
['OCA\Files_Sharing\External\Storage', false],
|
||||
['OCA\Files_Sharing\SharedStorage', false],
|
||||
]);
|
||||
$path->method('getStorage')->willReturn($storage);
|
||||
$this->rootFolder->method('getUserFolder')->with($this->currentUser)->willReturnSelf();
|
||||
$this->rootFolder->method('get')->with('valid-path')->willReturn($path);
|
||||
|
@ -2143,8 +2168,10 @@ class ShareAPIControllerTest extends TestCase {
|
|||
$path = $this->getMockBuilder(Folder::class)->getMock();
|
||||
$storage = $this->createMock(Storage::class);
|
||||
$storage->method('instanceOfStorage')
|
||||
->with('OCA\Files_Sharing\External\Storage')
|
||||
->willReturn(false);
|
||||
->willReturnMap([
|
||||
['OCA\Files_Sharing\External\Storage', false],
|
||||
['OCA\Files_Sharing\SharedStorage', false],
|
||||
]);
|
||||
$path->method('getStorage')->willReturn($storage);
|
||||
$path->method('getPath')->willReturn('valid-path');
|
||||
$this->rootFolder->method('getUserFolder')->with($this->currentUser)->willReturnSelf();
|
||||
|
@ -2179,8 +2206,10 @@ class ShareAPIControllerTest extends TestCase {
|
|||
$path = $this->getMockBuilder(Folder::class)->getMock();
|
||||
$storage = $this->createMock(Storage::class);
|
||||
$storage->method('instanceOfStorage')
|
||||
->with('OCA\Files_Sharing\External\Storage')
|
||||
->willReturn(false);
|
||||
->willReturnMap([
|
||||
['OCA\Files_Sharing\External\Storage', false],
|
||||
['OCA\Files_Sharing\SharedStorage', false],
|
||||
]);
|
||||
$path->method('getStorage')->willReturn($storage);
|
||||
$this->rootFolder->method('getUserFolder')->with($this->currentUser)->willReturnSelf();
|
||||
$this->rootFolder->method('get')->with('valid-path')->willReturn($path);
|
||||
|
@ -2222,8 +2251,10 @@ class ShareAPIControllerTest extends TestCase {
|
|||
$path = $this->getMockBuilder(Folder::class)->getMock();
|
||||
$storage = $this->createMock(Storage::class);
|
||||
$storage->method('instanceOfStorage')
|
||||
->with('OCA\Files_Sharing\External\Storage')
|
||||
->willReturn(false);
|
||||
->willReturnMap([
|
||||
['OCA\Files_Sharing\External\Storage', false],
|
||||
['OCA\Files_Sharing\SharedStorage', false],
|
||||
]);
|
||||
$path->method('getStorage')->willReturn($storage);
|
||||
$this->rootFolder->method('getUserFolder')->with($this->currentUser)->willReturnSelf();
|
||||
$this->rootFolder->method('get')->with('valid-path')->willReturn($path);
|
||||
|
@ -2270,8 +2301,10 @@ class ShareAPIControllerTest extends TestCase {
|
|||
$path = $this->getMockBuilder(File::class)->getMock();
|
||||
$storage = $this->createMock(Storage::class);
|
||||
$storage->method('instanceOfStorage')
|
||||
->with('OCA\Files_Sharing\External\Storage')
|
||||
->willReturn(false);
|
||||
->willReturnMap([
|
||||
['OCA\Files_Sharing\External\Storage', false],
|
||||
['OCA\Files_Sharing\SharedStorage', false],
|
||||
]);
|
||||
$path->method('getStorage')->willReturn($storage);
|
||||
$userFolder->expects($this->once())
|
||||
->method('get')
|
||||
|
@ -2342,8 +2375,10 @@ class ShareAPIControllerTest extends TestCase {
|
|||
$path = $this->getMockBuilder(File::class)->getMock();
|
||||
$storage = $this->createMock(Storage::class);
|
||||
$storage->method('instanceOfStorage')
|
||||
->with('OCA\Files_Sharing\External\Storage')
|
||||
->willReturn(false);
|
||||
->willReturnMap([
|
||||
['OCA\Files_Sharing\External\Storage', false],
|
||||
['OCA\Files_Sharing\SharedStorage', false],
|
||||
]);
|
||||
$path->method('getStorage')->willReturn($storage);
|
||||
$userFolder->expects($this->once())
|
||||
->method('get')
|
||||
|
@ -2396,8 +2431,10 @@ class ShareAPIControllerTest extends TestCase {
|
|||
$path = $this->getMockBuilder(File::class)->getMock();
|
||||
$storage = $this->createMock(Storage::class);
|
||||
$storage->method('instanceOfStorage')
|
||||
->with('OCA\Files_Sharing\External\Storage')
|
||||
->willReturn(false);
|
||||
->willReturnMap([
|
||||
['OCA\Files_Sharing\External\Storage', false],
|
||||
['OCA\Files_Sharing\SharedStorage', false],
|
||||
]);
|
||||
$path->method('getStorage')->willReturn($storage);
|
||||
$userFolder->expects($this->once())
|
||||
->method('get')
|
||||
|
@ -2480,8 +2517,10 @@ class ShareAPIControllerTest extends TestCase {
|
|||
$path = $this->getMockBuilder(File::class)->getMock();
|
||||
$storage = $this->createMock(Storage::class);
|
||||
$storage->method('instanceOfStorage')
|
||||
->with('OCA\Files_Sharing\External\Storage')
|
||||
->willReturn(false);
|
||||
->willReturnMap([
|
||||
['OCA\Files_Sharing\External\Storage', false],
|
||||
['OCA\Files_Sharing\SharedStorage', false],
|
||||
]);
|
||||
$path->method('getStorage')->willReturn($storage);
|
||||
$path->method('getPath')->willReturn('valid-path');
|
||||
$userFolder->expects($this->once())
|
||||
|
@ -2523,8 +2562,10 @@ class ShareAPIControllerTest extends TestCase {
|
|||
$path = $this->getMockBuilder(File::class)->getMock();
|
||||
$storage = $this->createMock(Storage::class);
|
||||
$storage->method('instanceOfStorage')
|
||||
->with('OCA\Files_Sharing\External\Storage')
|
||||
->willReturn(false);
|
||||
->willReturnMap([
|
||||
['OCA\Files_Sharing\External\Storage', false],
|
||||
['OCA\Files_Sharing\SharedStorage', false],
|
||||
]);
|
||||
$path->method('getStorage')->willReturn($storage);
|
||||
$userFolder->expects($this->once())
|
||||
->method('get')
|
||||
|
@ -2604,8 +2645,10 @@ class ShareAPIControllerTest extends TestCase {
|
|||
$path = $this->getMockBuilder(Folder::class)->getMock();
|
||||
$storage = $this->createMock(Storage::class);
|
||||
$storage->method('instanceOfStorage')
|
||||
->with('OCA\Files_Sharing\External\Storage')
|
||||
->willReturn(true);
|
||||
->willReturnMap([
|
||||
['OCA\Files_Sharing\External\Storage', true],
|
||||
['OCA\Files_Sharing\SharedStorage', false],
|
||||
]);
|
||||
$path->method('getStorage')->willReturn($storage);
|
||||
$path->method('getPermissions')->willReturn(\OCP\Constants::PERMISSION_READ);
|
||||
$userFolder->expects($this->once())
|
||||
|
@ -2964,8 +3007,17 @@ class ShareAPIControllerTest extends TestCase {
|
|||
$this->expectExceptionMessage('Invalid date. Format must be YYYY-MM-DD');
|
||||
|
||||
$ocs = $this->mockFormatShare();
|
||||
$userFolder = $this->createMock(Folder::class);
|
||||
$userFolder->method('getById')
|
||||
->with(42)
|
||||
->willReturn([]);
|
||||
$this->rootFolder->method('getUserFolder')
|
||||
->with($this->currentUser)
|
||||
->willReturn($userFolder);
|
||||
|
||||
$folder = $this->getMockBuilder(Folder::class)->getMock();
|
||||
$folder->method('getId')
|
||||
->willReturn(42);
|
||||
|
||||
$share = \OC::$server->getShareManager()->newShare();
|
||||
$share->setPermissions(\OCP\Constants::PERMISSION_ALL)
|
||||
|
@ -3003,8 +3055,16 @@ class ShareAPIControllerTest extends TestCase {
|
|||
$this->expectExceptionMessage('Public upload disabled by the administrator');
|
||||
|
||||
$ocs = $this->mockFormatShare();
|
||||
$userFolder = $this->createMock(Folder::class);
|
||||
$userFolder->method('getById')
|
||||
->with(42)
|
||||
->willReturn([]);
|
||||
$this->rootFolder->method('getUserFolder')
|
||||
->with($this->currentUser)
|
||||
->willReturn($userFolder);
|
||||
|
||||
$folder = $this->getMockBuilder(Folder::class)->getMock();
|
||||
$folder->method('getId')->willReturn(42);
|
||||
|
||||
$share = \OC::$server->getShareManager()->newShare();
|
||||
$share->setPermissions(\OCP\Constants::PERMISSION_ALL)
|
||||
|
@ -3026,6 +3086,15 @@ class ShareAPIControllerTest extends TestCase {
|
|||
$ocs = $this->mockFormatShare();
|
||||
|
||||
$file = $this->getMockBuilder(File::class)->getMock();
|
||||
$file->method('getId')
|
||||
->willReturn(42);
|
||||
$userFolder = $this->createMock(Folder::class);
|
||||
$userFolder->method('getById')
|
||||
->with(42)
|
||||
->willReturn([]);
|
||||
$this->rootFolder->method('getUserFolder')
|
||||
->with($this->currentUser)
|
||||
->willReturn($userFolder);
|
||||
|
||||
$share = \OC::$server->getShareManager()->newShare();
|
||||
$share->setPermissions(\OCP\Constants::PERMISSION_ALL)
|
||||
|
@ -3039,13 +3108,21 @@ class ShareAPIControllerTest extends TestCase {
|
|||
$ocs->updateShare(42, null, 'password', null, 'true', '');
|
||||
}
|
||||
|
||||
public function testUpdateLinkSharePasswordDoesNotChangeOther() {
|
||||
public function testUpdateLinkSharePasswordDoesNotChangeOther(): void {
|
||||
$ocs = $this->mockFormatShare();
|
||||
|
||||
$date = new \DateTime('2000-01-01');
|
||||
$date->setTime(0,0,0);
|
||||
|
||||
$node = $this->getMockBuilder(File::class)->getMock();
|
||||
$node->method('getId')->willReturn(42);
|
||||
$userFolder = $this->createMock(Folder::class);
|
||||
$userFolder->method('getById')
|
||||
->with(42)
|
||||
->willReturn([]);
|
||||
$this->rootFolder->method('getUserFolder')
|
||||
->with($this->currentUser)
|
||||
->willReturn($userFolder);
|
||||
$share = $this->newShare();
|
||||
$share->setPermissions(\OCP\Constants::PERMISSION_ALL)
|
||||
->setSharedBy($this->currentUser)
|
||||
|
@ -3090,7 +3167,15 @@ class ShareAPIControllerTest extends TestCase {
|
|||
$date = new \DateTime('2000-01-01');
|
||||
$date->setTime(0,0,0);
|
||||
|
||||
$userFolder = $this->createMock(Folder::class);
|
||||
$userFolder->method('getById')
|
||||
->with(42)
|
||||
->willReturn([]);
|
||||
$this->rootFolder->method('getUserFolder')
|
||||
->with($this->currentUser)
|
||||
->willReturn($userFolder);
|
||||
$node = $this->getMockBuilder(File::class)->getMock();
|
||||
$node->method('getId')->willReturn(42);
|
||||
$share = $this->newShare();
|
||||
$share->setPermissions(\OCP\Constants::PERMISSION_ALL)
|
||||
->setSharedBy($this->currentUser)
|
||||
|
@ -3141,7 +3226,15 @@ class ShareAPIControllerTest extends TestCase {
|
|||
$date = new \DateTime('2000-01-01');
|
||||
$date->setTime(0,0,0);
|
||||
|
||||
$userFolder = $this->createMock(Folder::class);
|
||||
$userFolder->method('getById')
|
||||
->with(42)
|
||||
->willReturn([]);
|
||||
$this->rootFolder->method('getUserFolder')
|
||||
->with($this->currentUser)
|
||||
->willReturn($userFolder);
|
||||
$node = $this->getMockBuilder(File::class)->getMock();
|
||||
$node->method('getId')->willReturn(42);
|
||||
$share = $this->newShare();
|
||||
$share->setPermissions(\OCP\Constants::PERMISSION_ALL)
|
||||
->setSharedBy($this->currentUser)
|
||||
|
@ -3174,7 +3267,15 @@ class ShareAPIControllerTest extends TestCase {
|
|||
$date = new \DateTime('2000-01-01');
|
||||
$date->setTime(0,0,0);
|
||||
|
||||
$userFolder = $this->createMock(Folder::class);
|
||||
$userFolder->method('getById')
|
||||
->with(42)
|
||||
->willReturn([]);
|
||||
$this->rootFolder->method('getUserFolder')
|
||||
->with($this->currentUser)
|
||||
->willReturn($userFolder);
|
||||
$node = $this->getMockBuilder(File::class)->getMock();
|
||||
$node->method('getId')->willReturn(42);
|
||||
$share = $this->newShare();
|
||||
$share->setPermissions(\OCP\Constants::PERMISSION_ALL)
|
||||
->setSharedBy($this->currentUser)
|
||||
|
|
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
|
@ -1,3 +1,3 @@
|
|||
/*! For license information please see core-files_fileinfo.js.LICENSE.txt */
|
||||
!function(i){var t=function(i){var t=this;_.each(i,(function(i,e){_.isFunction(i)||(t[e]=i)})),_.isUndefined(this.id)||(this.id=parseInt(i.id,10)),this.path=i.path||"","dir"===this.type?this.mimetype="httpd/unix-directory":this.mimetype=this.mimetype||"application/octet-stream",this.type||("httpd/unix-directory"===this.mimetype?this.type="dir":this.type="file")};t.prototype={id:null,name:null,path:null,mimetype:null,icon:null,type:null,permissions:null,mtime:null,etag:null,mountType:null,hasPreview:!0,sharePermissions:null,quotaAvailableBytes:-1},i.Files||(i.Files={}),i.Files.FileInfo=t}(OC);
|
||||
//# sourceMappingURL=core-files_fileinfo.js.map?v=d9cc5e8823977a1e870b
|
||||
!function(t){var i=function(t){var i=this;_.each(t,(function(t,e){_.isFunction(t)||(i[e]=t)})),_.isUndefined(this.id)||(this.id=parseInt(t.id,10)),this.path=t.path||"","dir"===this.type?this.mimetype="httpd/unix-directory":this.mimetype=this.mimetype||"application/octet-stream",this.type||("httpd/unix-directory"===this.mimetype?this.type="dir":this.type="file")};i.prototype={id:null,name:null,path:null,mimetype:null,icon:null,type:null,permissions:null,mtime:null,etag:null,mountType:null,hasPreview:!0,sharePermissions:null,shareAttributes:[],quotaAvailableBytes:-1,canDownload:function(){for(var t in this.shareAttributes){var i=this.shareAttributes[t];if("permissions"===i.scope&&"download"===i.key)return i.enabled}return!0}},t.Files||(t.Files={}),t.Files.FileInfo=i}(OC);
|
||||
//# sourceMappingURL=core-files_fileinfo.js.map?v=d5c54f8e5b3834c089a0
|
|
@ -1 +1 @@
|
|||
{"version":3,"file":"core-files_fileinfo.js?v=d9cc5e8823977a1e870b","mappings":";CA0BA,SAAUA,GAUT,IAAMC,EAAW,SAASC,GACzB,IAAMC,EAAOC,KACbC,EAAEC,KAAKJ,GAAM,SAASK,EAAOC,GACvBH,EAAEI,WAAWF,KACjBJ,EAAKK,GAAOD,MAITF,EAAEK,YAAYN,KAAKO,MACvBP,KAAKO,GAAKC,SAASV,EAAKS,GAAI,KAI7BP,KAAKS,KAAOX,EAAKW,MAAQ,GAEP,QAAdT,KAAKU,KACRV,KAAKW,SAAW,uBAEhBX,KAAKW,SAAWX,KAAKW,UAAY,2BAG7BX,KAAKU,OACa,yBAAlBV,KAAKW,SACRX,KAAKU,KAAO,MAEZV,KAAKU,KAAO,SAQfb,EAASe,UAAY,CAMpBL,GAAI,KAOJM,KAAM,KAQNJ,KAAM,KAONE,SAAU,KASVG,KAAM,KAQNJ,KAAM,KAQNK,YAAa,KAObC,MAAO,KAOPC,KAAM,KASNC,UAAW,KAKXC,YAAY,EAKZC,iBAAkB,KAElBC,qBAAsB,GAGlBzB,EAAG0B,QACP1B,EAAG0B,MAAQ,IAEZ1B,EAAG0B,MAAMzB,SAAWA,EAzIrB,CA0IGD","sources":["webpack:///nextcloud/core/src/files/fileinfo.js"],"sourcesContent":["/**\n * Copyright (c) 2015\n *\n * @author Julius Härtl <jus@bitgrid.net>\n * @author Robin Appelman <robin@icewind.nl>\n * @author Roeland Jago Douma <roeland@famdouma.nl>\n * @author Vincent Petry <vincent@nextcloud.com>\n *\n * @license AGPL-3.0-or-later\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as\n * published by the Free Software Foundation, either version 3 of the\n * License, or (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n *\n */\n\n/* eslint-disable */\n(function(OC) {\n\n\t/**\n\t * @class OC.Files.FileInfo\n\t * @classdesc File information\n\t *\n\t * @param {Object} data file data, see attributes for details\n\t *\n\t * @since 8.2\n\t */\n\tconst FileInfo = function(data) {\n\t\tconst self = this\n\t\t_.each(data, function(value, key) {\n\t\t\tif (!_.isFunction(value)) {\n\t\t\t\tself[key] = value\n\t\t\t}\n\t\t})\n\n\t\tif (!_.isUndefined(this.id)) {\n\t\t\tthis.id = parseInt(data.id, 10)\n\t\t}\n\n\t\t// TODO: normalize path\n\t\tthis.path = data.path || ''\n\n\t\tif (this.type === 'dir') {\n\t\t\tthis.mimetype = 'httpd/unix-directory'\n\t\t} else {\n\t\t\tthis.mimetype = this.mimetype || 'application/octet-stream'\n\t\t}\n\n\t\tif (!this.type) {\n\t\t\tif (this.mimetype === 'httpd/unix-directory') {\n\t\t\t\tthis.type = 'dir'\n\t\t\t} else {\n\t\t\t\tthis.type = 'file'\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * @memberof OC.Files\n\t */\n\tFileInfo.prototype = {\n\t\t/**\n\t\t * File id\n\t\t *\n\t\t * @type int\n\t\t */\n\t\tid: null,\n\n\t\t/**\n\t\t * File name\n\t\t *\n\t\t * @type String\n\t\t */\n\t\tname: null,\n\n\t\t/**\n\t\t * Path leading to the file, without the file name,\n\t\t * and with a leading slash.\n\t\t *\n\t\t * @type String\n\t\t */\n\t\tpath: null,\n\n\t\t/**\n\t\t * Mime type\n\t\t *\n\t\t * @type String\n\t\t */\n\t\tmimetype: null,\n\n\t\t/**\n\t\t * Icon URL.\n\t\t *\n\t\t * Can be used to override the mime type icon.\n\t\t *\n\t\t * @type String\n\t\t */\n\t\ticon: null,\n\n\t\t/**\n\t\t * File type. 'file' for files, 'dir' for directories.\n\t\t *\n\t\t * @type String\n\t\t * @deprecated rely on mimetype instead\n\t\t */\n\t\ttype: null,\n\n\t\t/**\n\t\t * Permissions.\n\t\t *\n\t\t * @see OC#PERMISSION_ALL for permissions\n\t\t * @type int\n\t\t */\n\t\tpermissions: null,\n\n\t\t/**\n\t\t * Modification time\n\t\t *\n\t\t * @type int\n\t\t */\n\t\tmtime: null,\n\n\t\t/**\n\t\t * Etag\n\t\t *\n\t\t * @type String\n\t\t */\n\t\tetag: null,\n\n\t\t/**\n\t\t * Mount type.\n\t\t *\n\t\t * One of null, \"external-root\", \"shared\" or \"shared-root\"\n\t\t *\n\t\t * @type string\n\t\t */\n\t\tmountType: null,\n\n\t\t/**\n\t\t * @type boolean\n\t\t */\n\t\thasPreview: true,\n\n\t\t/**\n\t\t * @type int\n\t\t */\n\t\tsharePermissions: null,\n\n\t\tquotaAvailableBytes: -1,\n\t}\n\n\tif (!OC.Files) {\n\t\tOC.Files = {}\n\t}\n\tOC.Files.FileInfo = FileInfo\n})(OC)\n"],"names":["OC","FileInfo","data","self","this","_","each","value","key","isFunction","isUndefined","id","parseInt","path","type","mimetype","prototype","name","icon","permissions","mtime","etag","mountType","hasPreview","sharePermissions","quotaAvailableBytes","Files"],"sourceRoot":""}
|
||||
{"version":3,"file":"core-files_fileinfo.js?v=d5c54f8e5b3834c089a0","mappings":";CA0BA,SAAUA,GAUT,IAAMC,EAAW,SAASC,GACzB,IAAMC,EAAOC,KACbC,EAAEC,KAAKJ,GAAM,SAASK,EAAOC,GACvBH,EAAEI,WAAWF,KACjBJ,EAAKK,GAAOD,MAITF,EAAEK,YAAYN,KAAKO,MACvBP,KAAKO,GAAKC,SAASV,EAAKS,GAAI,KAI7BP,KAAKS,KAAOX,EAAKW,MAAQ,GAEP,QAAdT,KAAKU,KACRV,KAAKW,SAAW,uBAEhBX,KAAKW,SAAWX,KAAKW,UAAY,2BAG7BX,KAAKU,OACa,yBAAlBV,KAAKW,SACRX,KAAKU,KAAO,MAEZV,KAAKU,KAAO,SAQfb,EAASe,UAAY,CAMpBL,GAAI,KAOJM,KAAM,KAQNJ,KAAM,KAONE,SAAU,KASVG,KAAM,KAQNJ,KAAM,KAQNK,YAAa,KAObC,MAAO,KAOPC,KAAM,KASNC,UAAW,KAKXC,YAAY,EAKZC,iBAAkB,KAKlBC,gBAAiB,GAEjBC,qBAAsB,EAEtBC,YAAa,WACZ,IAAK,IAAMC,KAAKxB,KAAKqB,gBAAiB,CACrC,IAAMI,EAAOzB,KAAKqB,gBAAgBG,GAClC,GAAmB,gBAAfC,EAAKC,OAAwC,aAAbD,EAAKrB,IACxC,OAAOqB,EAAKE,QAId,OAAO,IAIJ/B,EAAGgC,QACPhC,EAAGgC,MAAQ,IAEZhC,EAAGgC,MAAM/B,SAAWA,EAzJrB,CA0JGD","sources":["webpack:///nextcloud/core/src/files/fileinfo.js"],"sourcesContent":["/**\n * Copyright (c) 2015\n *\n * @author Julius Härtl <jus@bitgrid.net>\n * @author Robin Appelman <robin@icewind.nl>\n * @author Roeland Jago Douma <roeland@famdouma.nl>\n * @author Vincent Petry <vincent@nextcloud.com>\n *\n * @license AGPL-3.0-or-later\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as\n * published by the Free Software Foundation, either version 3 of the\n * License, or (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n *\n */\n\n/* eslint-disable */\n(function(OC) {\n\n\t/**\n\t * @class OC.Files.FileInfo\n\t * @classdesc File information\n\t *\n\t * @param {Object} data file data, see attributes for details\n\t *\n\t * @since 8.2\n\t */\n\tconst FileInfo = function(data) {\n\t\tconst self = this\n\t\t_.each(data, function(value, key) {\n\t\t\tif (!_.isFunction(value)) {\n\t\t\t\tself[key] = value\n\t\t\t}\n\t\t})\n\n\t\tif (!_.isUndefined(this.id)) {\n\t\t\tthis.id = parseInt(data.id, 10)\n\t\t}\n\n\t\t// TODO: normalize path\n\t\tthis.path = data.path || ''\n\n\t\tif (this.type === 'dir') {\n\t\t\tthis.mimetype = 'httpd/unix-directory'\n\t\t} else {\n\t\t\tthis.mimetype = this.mimetype || 'application/octet-stream'\n\t\t}\n\n\t\tif (!this.type) {\n\t\t\tif (this.mimetype === 'httpd/unix-directory') {\n\t\t\t\tthis.type = 'dir'\n\t\t\t} else {\n\t\t\t\tthis.type = 'file'\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * @memberof OC.Files\n\t */\n\tFileInfo.prototype = {\n\t\t/**\n\t\t * File id\n\t\t *\n\t\t * @type int\n\t\t */\n\t\tid: null,\n\n\t\t/**\n\t\t * File name\n\t\t *\n\t\t * @type String\n\t\t */\n\t\tname: null,\n\n\t\t/**\n\t\t * Path leading to the file, without the file name,\n\t\t * and with a leading slash.\n\t\t *\n\t\t * @type String\n\t\t */\n\t\tpath: null,\n\n\t\t/**\n\t\t * Mime type\n\t\t *\n\t\t * @type String\n\t\t */\n\t\tmimetype: null,\n\n\t\t/**\n\t\t * Icon URL.\n\t\t *\n\t\t * Can be used to override the mime type icon.\n\t\t *\n\t\t * @type String\n\t\t */\n\t\ticon: null,\n\n\t\t/**\n\t\t * File type. 'file' for files, 'dir' for directories.\n\t\t *\n\t\t * @type String\n\t\t * @deprecated rely on mimetype instead\n\t\t */\n\t\ttype: null,\n\n\t\t/**\n\t\t * Permissions.\n\t\t *\n\t\t * @see OC#PERMISSION_ALL for permissions\n\t\t * @type int\n\t\t */\n\t\tpermissions: null,\n\n\t\t/**\n\t\t * Modification time\n\t\t *\n\t\t * @type int\n\t\t */\n\t\tmtime: null,\n\n\t\t/**\n\t\t * Etag\n\t\t *\n\t\t * @type String\n\t\t */\n\t\tetag: null,\n\n\t\t/**\n\t\t * Mount type.\n\t\t *\n\t\t * One of null, \"external-root\", \"shared\" or \"shared-root\"\n\t\t *\n\t\t * @type string\n\t\t */\n\t\tmountType: null,\n\n\t\t/**\n\t\t * @type boolean\n\t\t */\n\t\thasPreview: true,\n\n\t\t/**\n\t\t * @type int\n\t\t */\n\t\tsharePermissions: null,\n\n\t\t/**\n\t\t * @type Array\n\t\t */\n\t\tshareAttributes: [],\n\n\t\tquotaAvailableBytes: -1,\n\n\t\tcanDownload: function() {\n\t\t\tfor (const i in this.shareAttributes) {\n\t\t\t\tconst attr = this.shareAttributes[i]\n\t\t\t\tif (attr.scope === 'permissions' && attr.key === 'download') {\n\t\t\t\t\treturn attr.enabled\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn true\n\t\t},\n\t}\n\n\tif (!OC.Files) {\n\t\tOC.Files = {}\n\t}\n\tOC.Files.FileInfo = FileInfo\n})(OC)\n"],"names":["OC","FileInfo","data","self","this","_","each","value","key","isFunction","isUndefined","id","parseInt","path","type","mimetype","prototype","name","icon","permissions","mtime","etag","mountType","hasPreview","sharePermissions","shareAttributes","quotaAvailableBytes","canDownload","i","attr","scope","enabled","Files"],"sourceRoot":""}
|
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
|
@ -266,8 +266,10 @@ return array(
|
|||
'OCP\\Files\\Config\\IUserMountCache' => $baseDir . '/lib/public/Files/Config/IUserMountCache.php',
|
||||
'OCP\\Files\\EmptyFileNameException' => $baseDir . '/lib/public/Files/EmptyFileNameException.php',
|
||||
'OCP\\Files\\EntityTooLargeException' => $baseDir . '/lib/public/Files/EntityTooLargeException.php',
|
||||
'OCP\\Files\\Events\\BeforeDirectFileDownloadEvent' => $baseDir . '/lib/public/Files/Events/BeforeDirectFileDownloadEvent.php',
|
||||
'OCP\\Files\\Events\\BeforeFileScannedEvent' => $baseDir . '/lib/public/Files/Events/BeforeFileScannedEvent.php',
|
||||
'OCP\\Files\\Events\\BeforeFolderScannedEvent' => $baseDir . '/lib/public/Files/Events/BeforeFolderScannedEvent.php',
|
||||
'OCP\\Files\\Events\\BeforeZipCreatedEvent' => $baseDir . '/lib/public/Files/Events/BeforeZipCreatedEvent.php',
|
||||
'OCP\\Files\\Events\\FileCacheUpdated' => $baseDir . '/lib/public/Files/Events/FileCacheUpdated.php',
|
||||
'OCP\\Files\\Events\\FileScannedEvent' => $baseDir . '/lib/public/Files/Events/FileScannedEvent.php',
|
||||
'OCP\\Files\\Events\\FolderScannedEvent' => $baseDir . '/lib/public/Files/Events/FolderScannedEvent.php',
|
||||
|
|
|
@ -299,8 +299,10 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
|
|||
'OCP\\Files\\Config\\IUserMountCache' => __DIR__ . '/../../..' . '/lib/public/Files/Config/IUserMountCache.php',
|
||||
'OCP\\Files\\EmptyFileNameException' => __DIR__ . '/../../..' . '/lib/public/Files/EmptyFileNameException.php',
|
||||
'OCP\\Files\\EntityTooLargeException' => __DIR__ . '/../../..' . '/lib/public/Files/EntityTooLargeException.php',
|
||||
'OCP\\Files\\Events\\BeforeDirectFileDownloadEvent' => __DIR__ . '/../../..' . '/lib/public/Files/Events/BeforeDirectFileDownloadEvent.php',
|
||||
'OCP\\Files\\Events\\BeforeFileScannedEvent' => __DIR__ . '/../../..' . '/lib/public/Files/Events/BeforeFileScannedEvent.php',
|
||||
'OCP\\Files\\Events\\BeforeFolderScannedEvent' => __DIR__ . '/../../..' . '/lib/public/Files/Events/BeforeFolderScannedEvent.php',
|
||||
'OCP\\Files\\Events\\BeforeZipCreatedEvent' => __DIR__ . '/../../..' . '/lib/public/Files/Events/BeforeZipCreatedEvent.php',
|
||||
'OCP\\Files\\Events\\FileCacheUpdated' => __DIR__ . '/../../..' . '/lib/public/Files/Events/FileCacheUpdated.php',
|
||||
'OCP\\Files\\Events\\FileScannedEvent' => __DIR__ . '/../../..' . '/lib/public/Files/Events/FileScannedEvent.php',
|
||||
'OCP\\Files\\Events\\FolderScannedEvent' => __DIR__ . '/../../..' . '/lib/public/Files/Events/FolderScannedEvent.php',
|
||||
|
|
|
@ -1566,14 +1566,15 @@ class DefaultShareProvider implements IShareProvider {
|
|||
/**
|
||||
* Load from database format (JSON string) to IAttributes
|
||||
*
|
||||
* @param IShare $share
|
||||
* @param string|null $data
|
||||
* @return IShare modified share
|
||||
* @return IShare the modified share
|
||||
*/
|
||||
private function updateShareAttributes(IShare $share, ?string $data) {
|
||||
private function updateShareAttributes(IShare $share, ?string $data): IShare {
|
||||
if ($data !== null && $data !== '') {
|
||||
$attributes = new ShareAttributes();
|
||||
$compressedAttributes = \json_decode($data, true);
|
||||
if ($compressedAttributes === false || $compressedAttributes === null) {
|
||||
return $share;
|
||||
}
|
||||
foreach ($compressedAttributes as $compressedAttribute) {
|
||||
$attributes->setAttribute(
|
||||
$compressedAttribute[0],
|
||||
|
@ -1589,11 +1590,8 @@ class DefaultShareProvider implements IShareProvider {
|
|||
|
||||
/**
|
||||
* Format IAttributes to database format (JSON string)
|
||||
*
|
||||
* @param IAttributes|null $attributes
|
||||
* @return string|null
|
||||
*/
|
||||
private function formatShareAttributes($attributes) {
|
||||
private function formatShareAttributes(?IAttributes $attributes): ?string {
|
||||
if ($attributes === null || empty($attributes->toArray())) {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -44,12 +44,12 @@ use bantu\IniGetWrapper\IniGetWrapper;
|
|||
use OC\Files\View;
|
||||
use OC\Streamer;
|
||||
use OCP\Lock\ILockingProvider;
|
||||
use OCP\EventDispatcher\GenericEvent;
|
||||
use OCP\Files\Events\BeforeZipCreatedEvent;
|
||||
use OCP\Files\Events\BeforeDirectFileDownloadEvent;
|
||||
use OCP\EventDispatcher\IEventDispatcher;
|
||||
|
||||
/**
|
||||
* Class for file server access
|
||||
*
|
||||
*/
|
||||
class OC_Files {
|
||||
public const FILE = 1;
|
||||
|
@ -170,11 +170,11 @@ class OC_Files {
|
|||
}
|
||||
|
||||
//Dispatch an event to see if any apps have problem with download
|
||||
$event = new GenericEvent(null, ['dir' => $dir, 'files' => $files, 'run' => true]);
|
||||
$dispatcher = \OC::$server->query(IEventDispatcher::class);
|
||||
$dispatcher->dispatch('file.beforeCreateZip', $event);
|
||||
if (($event->getArgument('run') === false) or ($event->hasArgument('errorMessage'))) {
|
||||
throw new \OC\ForbiddenException($event->getArgument('errorMessage'));
|
||||
$event = new BeforeZipCreatedEvent($dir, is_array($files) ? $files : [$files]);
|
||||
$dispatcher = \OCP\Server::get(IEventDispatcher::class);
|
||||
$dispatcher->dispatchTyped($event);
|
||||
if ((!$event->isSuccessful()) || $event->getErrorMessage() !== null) {
|
||||
throw new \OC\ForbiddenException($event->getErrorMessage());
|
||||
}
|
||||
|
||||
$streamer = new Streamer(\OC::$server->getRequest(), $fileSize, $numberOfFiles);
|
||||
|
@ -222,8 +222,6 @@ class OC_Files {
|
|||
$streamer->finalize();
|
||||
set_time_limit($executionTime);
|
||||
self::unlockAllTheFiles($dir, $files, $getType, $view, $filename);
|
||||
$event = new GenericEvent(null, ['result' => 'success', 'dir' => $dir, 'files' => $files]);
|
||||
$dispatcher->dispatch('file.afterCreateZip', $event);
|
||||
} catch (\OCP\Lock\LockedException $ex) {
|
||||
self::unlockAllTheFiles($dir, $files, $getType, $view, $filename);
|
||||
OC::$server->getLogger()->logException($ex);
|
||||
|
@ -240,8 +238,8 @@ class OC_Files {
|
|||
OC::$server->getLogger()->logException($ex);
|
||||
$l = \OC::$server->getL10N('lib');
|
||||
$hint = method_exists($ex, 'getHint') ? $ex->getHint() : '';
|
||||
if ($event && $event->hasArgument('message')) {
|
||||
$hint .= ' ' . $event->getArgument('message');
|
||||
if ($event && $event->getErrorMessage() !== null) {
|
||||
$hint .= ' ' . $event->getErrorMessage();
|
||||
}
|
||||
\OC_Template::printErrorPage($l->t('Cannot download file'), $hint, 200);
|
||||
}
|
||||
|
@ -339,12 +337,12 @@ class OC_Files {
|
|||
}
|
||||
|
||||
$dispatcher = \OC::$server->query(IEventDispatcher::class);
|
||||
$event = new GenericEvent(null, ['path' => $filename]);
|
||||
$dispatcher->dispatch('file.beforeGetDirect', $event);
|
||||
$event = new BeforeDirectFileDownloadEvent($filename);
|
||||
$dispatcher->dispatchTyped($event);
|
||||
|
||||
if (!\OC\Files\Filesystem::isReadable($filename) || $event->hasArgument('errorMessage')) {
|
||||
if (!$event->hasArgument('errorMessage')) {
|
||||
$msg = $event->getArgument('errorMessage');
|
||||
if (!\OC\Files\Filesystem::isReadable($filename) || $event->getErrorMessage()) {
|
||||
if ($event->getErrorMessage()) {
|
||||
$msg = $event->getErrorMessage();
|
||||
} else {
|
||||
$msg = 'Access denied';
|
||||
}
|
||||
|
|
|
@ -0,0 +1,84 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @copyright 2022 Carl Schwan <carl@carlschwan.eu>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
namespace OCP\Files\Events;
|
||||
|
||||
use OCP\EventDispatcher\Event;
|
||||
|
||||
/**
|
||||
* This event is triggered when a user tries to download a file
|
||||
* directly.
|
||||
*
|
||||
* @since 25.0.0
|
||||
*/
|
||||
class BeforeDirectFileDownloadEvent extends Event {
|
||||
private string $path;
|
||||
private bool $successful = true;
|
||||
private ?string $errorMessage = null;
|
||||
|
||||
/**
|
||||
* @since 25.0.0
|
||||
*/
|
||||
public function __construct(string $path) {
|
||||
parent::__construct();
|
||||
$this->path = $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 25.0.0
|
||||
*/
|
||||
public function getPath(): string {
|
||||
return $this->path;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 25.0.0
|
||||
*/
|
||||
public function isSuccessful(): bool {
|
||||
return $this->successful;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set if the event was successful
|
||||
*
|
||||
* @since 25.0.0
|
||||
*/
|
||||
public function setSuccessful(bool $successful): void {
|
||||
$this->successful = $successful;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the error message, if any
|
||||
* @since 25.0.0
|
||||
*/
|
||||
public function getErrorMessage(): ?string {
|
||||
return $this->errorMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 25.0.0
|
||||
*/
|
||||
public function setErrorMessage(string $errorMessage): void {
|
||||
$this->errorMessage = $errorMessage;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,91 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @copyright 2022 Carl Schwan <carl@carlschwan.eu>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OCP\Files\Events;
|
||||
|
||||
use OCP\EventDispatcher\Event;
|
||||
|
||||
/**
|
||||
* @since 25.0.0
|
||||
*/
|
||||
class BeforeZipCreatedEvent extends Event {
|
||||
private string $directory;
|
||||
private array $files;
|
||||
private bool $successful = true;
|
||||
private ?string $errorMessage = null;
|
||||
|
||||
/**
|
||||
* @since 25.0.0
|
||||
*/
|
||||
public function __construct(string $directory, array $files) {
|
||||
parent::__construct();
|
||||
$this->directory = $directory;
|
||||
$this->files = $files;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 25.0.0
|
||||
*/
|
||||
public function getDirectory(): string {
|
||||
return $this->directory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 25.0.0
|
||||
*/
|
||||
public function getFiles(): array {
|
||||
return $this->files;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 25.0.0
|
||||
*/
|
||||
public function isSuccessful(): bool {
|
||||
return $this->successful;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set if the event was successful
|
||||
*
|
||||
* @since 25.0.0
|
||||
*/
|
||||
public function setSuccessful(bool $successful): void {
|
||||
$this->successful = $successful;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the error message, if any
|
||||
* @since 25.0.0
|
||||
*/
|
||||
public function getErrorMessage(): ?string {
|
||||
return $this->errorMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 25.0.0
|
||||
*/
|
||||
public function setErrorMessage(string $errorMessage): void {
|
||||
$this->errorMessage = $errorMessage;
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче