1<?php
2/**
3 * @author Lukas Reschke <lukas@statuscode.ch>
4 * @author Thomas Müller <thomas.mueller@tmit.eu>
5 *
6 * @copyright Copyright (c) 2018, ownCloud GmbH
7 * @license AGPL-3.0
8 *
9 * This code is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU Affero General Public License, version 3,
11 * as published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Affero General Public License for more details.
17 *
18 * You should have received a copy of the GNU Affero General Public License, version 3,
19 * along with this program.  If not, see <http://www.gnu.org/licenses/>
20 *
21 */
22
23namespace OCA\DAV\Connector\Sabre;
24
25use Sabre\DAV\Exception\NotFound;
26use Sabre\DAV\INode;
27use Sabre\DAVACL\Plugin;
28
29/**
30 * Class DavAclPlugin is a wrapper around \Sabre\DAVACL\Plugin that returns 404
31 * responses in case the resource to a response has been forbidden instead of
32 * a 403. This is used to prevent enumeration of valid resources.
33 *
34 * @see https://github.com/owncloud/core/issues/22578
35 * @package OCA\DAV\Connector\Sabre
36 */
37class DavAclPlugin extends Plugin {
38	public function __construct() {
39		$this->hideNodesFromListings = true;
40		$this->allowUnauthenticatedAccess = false;
41	}
42
43	public function checkPrivileges($uri, $privileges, $recursion = self::R_PARENT, $throwExceptions = true) {
44		// within public-files throwing the exception NeedPrivileges is desired
45		$shallThrowExceptions = false;
46		$elements = \explode('/', $uri);
47		if ($elements[0] === 'public-files') {
48			$shallThrowExceptions = true;
49		}
50
51		$access = parent::checkPrivileges($uri, $privileges, $recursion, $shallThrowExceptions);
52		if ($access === false && $throwExceptions) {
53			/** @var INode $node */
54			$node = $this->server->tree->getNodeForPath($uri);
55
56			switch (\get_class($node)) {
57				case 'OCA\DAV\CardDAV\AddressBook':
58					$type = 'Addressbook';
59					break;
60				default:
61					$type = 'Node';
62					break;
63			}
64			throw new NotFound(
65				\sprintf(
66					"%s with name '%s' could not be found",
67					$type,
68					$node->getName()
69				)
70			);
71		}
72
73		return $access;
74	}
75}
76