|
14 | 14 | use OCA\Files_Sharing\Event\ShareLinkAccessedEvent; |
15 | 15 | use OCP\Accounts\IAccountManager; |
16 | 16 | use OCP\AppFramework\AuthPublicShareController; |
| 17 | +use OCP\AppFramework\Http; |
17 | 18 | use OCP\AppFramework\Http\Attribute\NoCSRFRequired; |
18 | 19 | use OCP\AppFramework\Http\Attribute\OpenAPI; |
19 | 20 | use OCP\AppFramework\Http\Attribute\PublicPage; |
|
29 | 30 | use OCP\Files\Folder; |
30 | 31 | use OCP\Files\IRootFolder; |
31 | 32 | use OCP\Files\NotFoundException; |
| 33 | +use OCP\Files\NotPermittedException; |
32 | 34 | use OCP\HintException; |
33 | 35 | use OCP\IConfig; |
34 | 36 | use OCP\IL10N; |
@@ -360,49 +362,75 @@ public function downloadShare($token, $files = null, $path = '') { |
360 | 362 | $share = $this->shareManager->getShareByToken($token); |
361 | 363 |
|
362 | 364 | if (!($share->getPermissions() & Constants::PERMISSION_READ)) { |
363 | | - return new DataResponse('Share has no read permission'); |
| 365 | + return new DataResponse('Share has no read permission', Http::STATUS_FORBIDDEN); |
364 | 366 | } |
365 | 367 |
|
366 | 368 | $attributes = $share->getAttributes(); |
367 | 369 | if ($attributes?->getAttribute('permissions', 'download') === false) { |
368 | | - return new DataResponse('Share has no download permission'); |
| 370 | + return new DataResponse('Share has no download permission', Http::STATUS_FORBIDDEN); |
369 | 371 | } |
370 | 372 |
|
371 | 373 | if (!$this->validateShare($share)) { |
372 | 374 | throw new NotFoundException(); |
373 | 375 | } |
374 | 376 |
|
| 377 | + if ($share->getHideDownload()) { |
| 378 | + // download API does not work if hidden - use the DAV endpoint for previews |
| 379 | + throw new NotFoundException(); |
| 380 | + } |
| 381 | + |
375 | 382 | $node = $share->getNode(); |
376 | | - if ($node instanceof Folder) { |
377 | | - // Directory share |
| 383 | + if ($path !== '') { |
| 384 | + if (!$node instanceof Folder) { |
| 385 | + return new NotFoundResponse(); |
| 386 | + } |
378 | 387 |
|
379 | | - // Try to get the path |
380 | | - if ($path !== '') { |
| 388 | + try { |
| 389 | + $node = $node->get($path); |
| 390 | + } catch (NotFoundException|NotPermittedException) { |
| 391 | + $this->emitAccessShareHook($share, 404, 'Share not found'); |
| 392 | + $this->emitShareAccessEvent($share, self::SHARE_DOWNLOAD, 404, 'Share not found'); |
| 393 | + return new NotFoundResponse(); |
| 394 | + } |
| 395 | + } |
| 396 | + |
| 397 | + if ($files !== null) { |
| 398 | + if (!$node instanceof Folder) { |
| 399 | + return new NotFoundResponse(); |
| 400 | + } |
| 401 | + |
| 402 | + $filesParam = json_decode($files, true); |
| 403 | + if (!is_array($filesParam)) { |
381 | 404 | try { |
382 | | - $node = $node->get($path); |
383 | | - } catch (NotFoundException $e) { |
| 405 | + // legacy wise this allows also passing the filename |
| 406 | + $node = $node->get($files); |
| 407 | + $files = null; |
| 408 | + } catch (NotFoundException|NotPermittedException) { |
384 | 409 | $this->emitAccessShareHook($share, 404, 'Share not found'); |
385 | 410 | $this->emitShareAccessEvent($share, self::SHARE_DOWNLOAD, 404, 'Share not found'); |
386 | 411 | return new NotFoundResponse(); |
387 | 412 | } |
388 | 413 | } |
389 | | - |
390 | | - if ($node instanceof Folder) { |
391 | | - if ($files === null || $files === '') { |
392 | | - if ($share->getHideDownload()) { |
393 | | - throw new NotFoundException('Downloading a folder'); |
394 | | - } |
395 | | - } |
396 | | - } |
397 | 414 | } |
398 | 415 |
|
399 | 416 | $this->emitAccessShareHook($share); |
400 | 417 | $this->emitShareAccessEvent($share, self::SHARE_DOWNLOAD); |
401 | 418 |
|
402 | | - $davUrl = '/public.php/dav/files/' . $token . '/?accept=zip'; |
| 419 | + $davPath = ''; |
| 420 | + if ($node !== $share->getNode()) { |
| 421 | + $davPath = substr($node->getPath(), strlen($share->getNode()->getPath())); |
| 422 | + } |
| 423 | + |
| 424 | + $params = []; |
403 | 425 | if ($files !== null) { |
404 | | - $davUrl .= '&files=' . $files; |
| 426 | + $params['files'] = $files; |
405 | 427 | } |
| 428 | + if ($node instanceof Folder) { |
| 429 | + $params['accept'] = 'zip'; |
| 430 | + } |
| 431 | + |
| 432 | + $davUrl = '/public.php/dav/files/' . $token . $davPath; |
| 433 | + $davUrl .= '?' . http_build_query($params); |
406 | 434 | return new RedirectResponse($this->urlGenerator->getAbsoluteURL($davUrl)); |
407 | 435 | } |
408 | 436 | } |
0 commit comments