mirror of
https://github.com/nextcloud/server.git
synced 2026-05-28 04:32:30 -04:00
Merge pull request #48438 from nextcloud/fix/bring-back-zip-event
fix(dav): Emit `BeforeZipCreatedEvent` when creating folder zip archive
This commit is contained in:
commit
02f3c88d73
4 changed files with 71 additions and 47 deletions
|
|
@ -28,39 +28,19 @@ use Psr\Log\LoggerInterface;
|
|||
use Sabre\DAV\Auth\Plugin;
|
||||
|
||||
class ServerFactory {
|
||||
private IConfig $config;
|
||||
private LoggerInterface $logger;
|
||||
private IDBConnection $databaseConnection;
|
||||
private IUserSession $userSession;
|
||||
private IMountManager $mountManager;
|
||||
private ITagManager $tagManager;
|
||||
private IRequest $request;
|
||||
private IPreview $previewManager;
|
||||
private IEventDispatcher $eventDispatcher;
|
||||
private IL10N $l10n;
|
||||
|
||||
public function __construct(
|
||||
IConfig $config,
|
||||
LoggerInterface $logger,
|
||||
IDBConnection $databaseConnection,
|
||||
IUserSession $userSession,
|
||||
IMountManager $mountManager,
|
||||
ITagManager $tagManager,
|
||||
IRequest $request,
|
||||
IPreview $previewManager,
|
||||
IEventDispatcher $eventDispatcher,
|
||||
IL10N $l10n,
|
||||
private IConfig $config,
|
||||
private LoggerInterface $logger,
|
||||
private IDBConnection $databaseConnection,
|
||||
private IUserSession $userSession,
|
||||
private IMountManager $mountManager,
|
||||
private ITagManager $tagManager,
|
||||
private IRequest $request,
|
||||
private IPreview $previewManager,
|
||||
private IEventDispatcher $eventDispatcher,
|
||||
private IL10N $l10n,
|
||||
) {
|
||||
$this->config = $config;
|
||||
$this->logger = $logger;
|
||||
$this->databaseConnection = $databaseConnection;
|
||||
$this->userSession = $userSession;
|
||||
$this->mountManager = $mountManager;
|
||||
$this->tagManager = $tagManager;
|
||||
$this->request = $request;
|
||||
$this->previewManager = $previewManager;
|
||||
$this->eventDispatcher = $eventDispatcher;
|
||||
$this->l10n = $l10n;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -80,7 +60,7 @@ class ServerFactory {
|
|||
// Load plugins
|
||||
$server->addPlugin(new \OCA\DAV\Connector\Sabre\MaintenancePlugin($this->config, $this->l10n));
|
||||
$server->addPlugin(new BlockLegacyClientPlugin(
|
||||
\OCP\Server::get(IConfig::class),
|
||||
$this->config,
|
||||
\OCP\Server::get(ThemingDefaults::class),
|
||||
));
|
||||
$server->addPlugin(new \OCA\DAV\Connector\Sabre\AnonymousOptionsPlugin());
|
||||
|
|
@ -90,11 +70,12 @@ class ServerFactory {
|
|||
$server->addPlugin(new \OCA\DAV\Connector\Sabre\ExceptionLoggerPlugin('webdav', $this->logger));
|
||||
$server->addPlugin(new \OCA\DAV\Connector\Sabre\LockPlugin());
|
||||
|
||||
$server->addPlugin(new RequestIdHeaderPlugin(\OC::$server->get(IRequest::class)));
|
||||
$server->addPlugin(new RequestIdHeaderPlugin($this->request));
|
||||
|
||||
$server->addPlugin(new ZipFolderPlugin(
|
||||
$objectTree,
|
||||
$this->logger,
|
||||
$this->eventDispatcher,
|
||||
));
|
||||
|
||||
// Some WebDAV clients do require Class 2 WebDAV support (locking), since
|
||||
|
|
|
|||
|
|
@ -9,6 +9,9 @@ declare(strict_types=1);
|
|||
namespace OCA\DAV\Connector\Sabre;
|
||||
|
||||
use OC\Streamer;
|
||||
use OCA\DAV\Connector\Sabre\Exception\Forbidden;
|
||||
use OCP\EventDispatcher\IEventDispatcher;
|
||||
use OCP\Files\Events\BeforeZipCreatedEvent;
|
||||
use OCP\Files\File as NcFile;
|
||||
use OCP\Files\Folder as NcFolder;
|
||||
use OCP\Files\Node as NcNode;
|
||||
|
|
@ -37,6 +40,7 @@ class ZipFolderPlugin extends ServerPlugin {
|
|||
public function __construct(
|
||||
private Tree $tree,
|
||||
private LoggerInterface $logger,
|
||||
private IEventDispatcher $eventDispatcher,
|
||||
) {
|
||||
}
|
||||
|
||||
|
|
@ -114,17 +118,33 @@ class ZipFolderPlugin extends ServerPlugin {
|
|||
if ($filesParam !== '') {
|
||||
$files = json_decode($filesParam);
|
||||
if (!is_array($files)) {
|
||||
if (!is_string($files)) {
|
||||
$files = [$files];
|
||||
}
|
||||
|
||||
foreach ($files as $file) {
|
||||
if (!is_string($file)) {
|
||||
// we log this as this means either we - or an app - have a bug somewhere or a user is trying invalid things
|
||||
$this->logger->notice('Invalid files filter parameter for ZipFolderPlugin', ['filter' => $filesParam]);
|
||||
// no valid parameter so continue with Sabre behavior
|
||||
$this->logger->debug('Invalid files filter parameter for ZipFolderPlugin', ['filter' => $filesParam]);
|
||||
return null;
|
||||
}
|
||||
|
||||
$files = [$files];
|
||||
}
|
||||
}
|
||||
|
||||
$folder = $node->getNode();
|
||||
$event = new BeforeZipCreatedEvent($folder, $files);
|
||||
$this->eventDispatcher->dispatchTyped($event);
|
||||
if ((!$event->isSuccessful()) || $event->getErrorMessage() !== null) {
|
||||
$errorMessage = $event->getErrorMessage();
|
||||
if ($errorMessage === null) {
|
||||
// Not allowed to download but also no explaining error
|
||||
// so we abort the ZIP creation and fall back to Sabre default behavior.
|
||||
return null;
|
||||
}
|
||||
// Downloading was denied by an app
|
||||
throw new Forbidden($errorMessage);
|
||||
}
|
||||
|
||||
$content = empty($files) ? $folder->getDirectoryListing() : [];
|
||||
foreach ($files as $path) {
|
||||
$child = $node->getChild($path);
|
||||
|
|
|
|||
|
|
@ -86,9 +86,9 @@ class Server {
|
|||
|
||||
$this->request = $request;
|
||||
$this->baseUri = $baseUri;
|
||||
$logger = \OC::$server->get(LoggerInterface::class);
|
||||
/** @var IEventDispatcher $dispatcher */
|
||||
$dispatcher = \OC::$server->get(IEventDispatcher::class);
|
||||
|
||||
$logger = \OCP\Server::get(LoggerInterface::class);
|
||||
$eventDispatcher = \OCP\Server::get(IEventDispatcher::class);
|
||||
|
||||
$root = new RootCollection();
|
||||
$this->server = new \OCA\DAV\Connector\Sabre\Server(new CachingTree($root));
|
||||
|
|
@ -123,10 +123,10 @@ class Server {
|
|||
|
||||
// allow setup of additional auth backends
|
||||
$event = new SabrePluginEvent($this->server);
|
||||
$dispatcher->dispatch('OCA\DAV\Connector\Sabre::authInit', $event);
|
||||
$eventDispatcher->dispatch('OCA\DAV\Connector\Sabre::authInit', $event);
|
||||
|
||||
$newAuthEvent = new SabrePluginAuthInitEvent($this->server);
|
||||
$dispatcher->dispatchTyped($newAuthEvent);
|
||||
$eventDispatcher->dispatchTyped($newAuthEvent);
|
||||
|
||||
$bearerAuthBackend = new BearerAuth(
|
||||
\OC::$server->getUserSession(),
|
||||
|
|
@ -213,12 +213,13 @@ class Server {
|
|||
$this->server->addPlugin(new ZipFolderPlugin(
|
||||
$this->server->tree,
|
||||
$logger,
|
||||
$eventDispatcher,
|
||||
));
|
||||
|
||||
// allow setup of additional plugins
|
||||
$dispatcher->dispatch('OCA\DAV\Connector\Sabre::addPlugin', $event);
|
||||
$eventDispatcher->dispatch('OCA\DAV\Connector\Sabre::addPlugin', $event);
|
||||
$typedEvent = new SabrePluginAddEvent($this->server);
|
||||
$dispatcher->dispatchTyped($typedEvent);
|
||||
$eventDispatcher->dispatchTyped($typedEvent);
|
||||
|
||||
// Some WebDAV clients do require Class 2 WebDAV support (locking), since
|
||||
// we do not provide locking we emulate it using a fake locking plugin.
|
||||
|
|
|
|||
|
|
@ -10,23 +10,45 @@ declare(strict_types=1);
|
|||
namespace OCP\Files\Events;
|
||||
|
||||
use OCP\EventDispatcher\Event;
|
||||
use OCP\Files\Folder;
|
||||
|
||||
/**
|
||||
* This event is triggered before a archive is created when a user requested
|
||||
* downloading a folder or multiple files.
|
||||
*
|
||||
* By setting `successful` to false the tar creation can be aborted and the download denied.
|
||||
*
|
||||
* @since 25.0.0
|
||||
*/
|
||||
class BeforeZipCreatedEvent extends Event {
|
||||
private string $directory;
|
||||
private array $files;
|
||||
private bool $successful = true;
|
||||
private ?string $errorMessage = null;
|
||||
private ?Folder $folder = null;
|
||||
|
||||
/**
|
||||
* @param list<string> $files
|
||||
* @since 25.0.0
|
||||
* @since 31.0.0 support `OCP\Files\Folder` as `$directory` parameter - passing a string is deprecated now
|
||||
*/
|
||||
public function __construct(string $directory, array $files) {
|
||||
public function __construct(
|
||||
string|Folder $directory,
|
||||
private array $files,
|
||||
) {
|
||||
parent::__construct();
|
||||
$this->directory = $directory;
|
||||
$this->files = $files;
|
||||
if ($directory instanceof Folder) {
|
||||
$this->directory = $directory->getPath();
|
||||
$this->folder = $directory;
|
||||
} else {
|
||||
$this->directory = $directory;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 31.0.0
|
||||
*/
|
||||
public function getFolder(): ?Folder {
|
||||
return $this->folder;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Reference in a new issue