Merge pull request #25563 from nextcloud/direct-download-event

add event for when a direct download is triggered
This commit is contained in:
Christoph Wurst 2021-02-12 19:02:51 +01:00 committed by GitHub
commit c1b2ca8489
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 97 additions and 14 deletions

View File

@ -25,6 +25,8 @@ declare(strict_types=1);
*
*/
use \OCA\DAV\Direct\ServerFactory;
// no php execution timeout for webdav
if (strpos(@ini_get('disable_functions'), 'set_time_limit') === false) {
@set_time_limit(0);
@ -36,7 +38,8 @@ ignore_user_abort(true);
$requestUri = \OC::$server->getRequest()->getRequestUri();
$serverFactory = new \OCA\DAV\Direct\ServerFactory(\OC::$server->getConfig(), \OC::$server->getL10N('dav'));
/** @var ServerFactory $serverFactory */
$serverFactory = \OC::$server->query(ServerFactory::class);
$server = $serverFactory->createServer(
$baseuri,
$requestUri,

View File

@ -176,6 +176,7 @@ return array(
'OCA\\DAV\\Events\\AddressBookDeletedEvent' => $baseDir . '/../lib/Events/AddressBookDeletedEvent.php',
'OCA\\DAV\\Events\\AddressBookShareUpdatedEvent' => $baseDir . '/../lib/Events/AddressBookShareUpdatedEvent.php',
'OCA\\DAV\\Events\\AddressBookUpdatedEvent' => $baseDir . '/../lib/Events/AddressBookUpdatedEvent.php',
'OCA\\DAV\\Events\\BeforeFileDirectDownloadedEvent' => $baseDir . '/../lib/Events/BeforeFileDirectDownloadedEvent.php',
'OCA\\DAV\\Events\\CachedCalendarObjectCreatedEvent' => $baseDir . '/../lib/Events/CachedCalendarObjectCreatedEvent.php',
'OCA\\DAV\\Events\\CachedCalendarObjectDeletedEvent' => $baseDir . '/../lib/Events/CachedCalendarObjectDeletedEvent.php',
'OCA\\DAV\\Events\\CachedCalendarObjectUpdatedEvent' => $baseDir . '/../lib/Events/CachedCalendarObjectUpdatedEvent.php',

View File

@ -191,6 +191,7 @@ class ComposerStaticInitDAV
'OCA\\DAV\\Events\\AddressBookDeletedEvent' => __DIR__ . '/..' . '/../lib/Events/AddressBookDeletedEvent.php',
'OCA\\DAV\\Events\\AddressBookShareUpdatedEvent' => __DIR__ . '/..' . '/../lib/Events/AddressBookShareUpdatedEvent.php',
'OCA\\DAV\\Events\\AddressBookUpdatedEvent' => __DIR__ . '/..' . '/../lib/Events/AddressBookUpdatedEvent.php',
'OCA\\DAV\\Events\\BeforeFileDirectDownloadedEvent' => __DIR__ . '/..' . '/../lib/Events/BeforeFileDirectDownloadedEvent.php',
'OCA\\DAV\\Events\\CachedCalendarObjectCreatedEvent' => __DIR__ . '/..' . '/../lib/Events/CachedCalendarObjectCreatedEvent.php',
'OCA\\DAV\\Events\\CachedCalendarObjectDeletedEvent' => __DIR__ . '/..' . '/../lib/Events/CachedCalendarObjectDeletedEvent.php',
'OCA\\DAV\\Events\\CachedCalendarObjectUpdatedEvent' => __DIR__ . '/..' . '/../lib/Events/CachedCalendarObjectUpdatedEvent.php',

View File

@ -27,6 +27,8 @@ declare(strict_types=1);
namespace OCA\DAV\Direct;
use OCA\DAV\Db\Direct;
use OCA\DAV\Events\BeforeFileDirectDownloadedEvent;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\Files\File;
use OCP\Files\IRootFolder;
use Sabre\DAV\Exception\Forbidden;
@ -43,9 +45,12 @@ class DirectFile implements IFile {
/** @var File */
private $file;
public function __construct(Direct $direct, IRootFolder $rootFolder) {
private $eventDispatcher;
public function __construct(Direct $direct, IRootFolder $rootFolder, IEventDispatcher $eventDispatcher) {
$this->direct = $direct;
$this->rootFolder = $rootFolder;
$this->eventDispatcher = $eventDispatcher;
}
public function put($data) {
@ -55,6 +60,8 @@ class DirectFile implements IFile {
public function get() {
$this->getFile();
$this->eventDispatcher->dispatchTyped(new BeforeFileDirectDownloadedEvent($this->file));
return $this->file->fopen('rb');
}

View File

@ -30,6 +30,7 @@ use OC\Security\Bruteforce\Throttler;
use OCA\DAV\Db\DirectMapper;
use OCP\AppFramework\Db\DoesNotExistException;
use OCP\AppFramework\Utility\ITimeFactory;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\Files\IRootFolder;
use OCP\IRequest;
use Sabre\DAV\Exception\Forbidden;
@ -53,17 +54,22 @@ class DirectHome implements ICollection {
/** @var IRequest */
private $request;
private $eventDispatcher;
public function __construct(IRootFolder $rootFolder,
public function __construct(
IRootFolder $rootFolder,
DirectMapper $mapper,
ITimeFactory $timeFactory,
Throttler $throttler,
IRequest $request) {
IRequest $request,
IEventDispatcher $eventDispatcher
) {
$this->rootFolder = $rootFolder;
$this->mapper = $mapper;
$this->timeFactory = $timeFactory;
$this->throttler = $throttler;
$this->request = $request;
$this->eventDispatcher = $eventDispatcher;
}
public function createFile($name, $data = null) {
@ -83,7 +89,7 @@ class DirectHome implements ICollection {
throw new NotFound();
}
return new DirectFile($direct, $this->rootFolder);
return new DirectFile($direct, $this->rootFolder, $this->eventDispatcher);
} catch (DoesNotExistException $e) {
// Since the token space is so huge only throttle on non exsisting token
$this->throttler->registerAttempt('directlink', $this->request->getRemoteAddress());

View File

@ -28,22 +28,27 @@ declare(strict_types=1);
namespace OCA\DAV\Direct;
use OC\Security\Bruteforce\Throttler;
use OCA\DAV\Connector\Sabre\MaintenancePlugin;
use OCA\DAV\Db\DirectMapper;
use OCP\AppFramework\Utility\ITimeFactory;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\Files\IRootFolder;
use OCP\IConfig;
use OCP\IL10N;
use OCP\IRequest;
use OCP\L10N\IFactory;
class ServerFactory {
/** @var IConfig */
private $config;
/** @var IL10N */
private $l10n;
private $eventDispatcher;
public function __construct(IConfig $config, IL10N $l10n) {
public function __construct(IConfig $config, IFactory $l10nFactory, IEventDispatcher $eventDispatcher) {
$this->config = $config;
$this->l10n = $l10n;
$this->l10n = $l10nFactory->get('dav');
$this->eventDispatcher = $eventDispatcher;
}
public function createServer(string $baseURI,
@ -53,13 +58,13 @@ class ServerFactory {
ITimeFactory $timeFactory,
Throttler $throttler,
IRequest $request): Server {
$home = new DirectHome($rootFolder, $mapper, $timeFactory, $throttler, $request);
$home = new DirectHome($rootFolder, $mapper, $timeFactory, $throttler, $request, $this->eventDispatcher);
$server = new Server($home);
$server->httpRequest->setUrl($requestURI);
$server->setBaseUri($baseURI);
$server->addPlugin(new \OCA\DAV\Connector\Sabre\MaintenancePlugin($this->config, $this->l10n));
$server->addPlugin(new MaintenancePlugin($this->config, $this->l10n));
return $server;
}

View File

@ -0,0 +1,47 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2021 Robin Appelman <robin@icewind.nl>
*
* @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 OCA\DAV\Events;
use OCP\EventDispatcher\Event;
use OCP\Files\File;
/**
* @since 22.0.0
*/
class BeforeFileDirectDownloadedEvent extends Event {
private $file;
public function __construct(File $file) {
parent::__construct();
$this->file = $file;
}
/**
* @return File
* @since 22.0.0
*/
public function getFile(): File {
return $this->file;
}
}

View File

@ -29,6 +29,7 @@ namespace OCA\DAV\Tests\Unit\Direct;
use OCA\DAV\Db\Direct;
use OCA\DAV\Direct\DirectFile;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\Files\File;
use OCP\Files\Folder;
use OCP\Files\IRootFolder;
@ -52,6 +53,9 @@ class DirectFileTest extends TestCase {
/** @var DirectFile */
private $directFile;
/** @var IEventDispatcher */
private $eventDispatcher;
protected function setUp(): void {
parent::setUp();
@ -73,7 +77,9 @@ class DirectFileTest extends TestCase {
->with(42)
->willReturn([$this->file]);
$this->directFile = new DirectFile($this->direct, $this->rootFolder);
$this->eventDispatcher = $this->createMock(IEventDispatcher::class);
$this->directFile = new DirectFile($this->direct, $this->rootFolder, $this->eventDispatcher);
}
public function testPut() {

View File

@ -34,6 +34,7 @@ use OCA\DAV\Direct\DirectFile;
use OCA\DAV\Direct\DirectHome;
use OCP\AppFramework\Db\DoesNotExistException;
use OCP\AppFramework\Utility\ITimeFactory;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\Files\IRootFolder;
use OCP\IRequest;
use Sabre\DAV\Exception\Forbidden;
@ -61,6 +62,9 @@ class DirectHomeTest extends TestCase {
/** @var DirectHome */
private $directHome;
/** @var IEventDispatcher */
private $eventDispatcher;
protected function setUp(): void {
parent::setUp();
@ -69,6 +73,7 @@ class DirectHomeTest extends TestCase {
$this->timeFactory = $this->createMock(ITimeFactory::class);
$this->throttler = $this->createMock(Throttler::class);
$this->request = $this->createMock(IRequest::class);
$this->eventDispatcher = $this->createMock(IEventDispatcher::class);
$this->timeFactory->method('getTime')
->willReturn(42);
@ -76,12 +81,14 @@ class DirectHomeTest extends TestCase {
$this->request->method('getRemoteAddress')
->willReturn('1.2.3.4');
$this->directHome = new DirectHome(
$this->rootFolder,
$this->directMapper,
$this->timeFactory,
$this->throttler,
$this->request
$this->request,
$this->eventDispatcher
);
}