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