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