Issues (9)

src/DAV/SearchPlugin.php (1 issue)

Severity
1
<?php declare(strict_types=1);
2
/**
3
 * @copyright Copyright (c) 2017 Robin Appelman <[email protected]>
4
 *
5
 * @license GNU AGPL version 3 or any later version
6
 *
7
 * This program is free software: you can redistribute it and/or modify
8
 * it under the terms of the GNU Affero General Public License as
9
 * published by the Free Software Foundation, either version 3 of the
10
 * License, or (at your option) any later version.
11
 *
12
 * This program is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU Affero General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Affero General Public License
18
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
 *
20
 */
21
22
namespace SearchDAV\DAV;
23
24
use Sabre\DAV\INode;
25
use Sabre\DAV\PropFind;
26
use Sabre\DAV\Server;
27
use Sabre\DAV\ServerPlugin;
28
use Sabre\HTTP\RequestInterface;
29
use Sabre\HTTP\ResponseInterface;
30
use Sabre\Xml\ParseException;
31
use SearchDAV\Backend\ISearchBackend;
32
use SearchDAV\XML\SupportedQueryGrammar;
33
34
class SearchPlugin extends ServerPlugin {
35
	const SEARCHDAV_NS = 'https://github.com/icewind1991/SearchDAV/ns';
36
37
	/** @var Server */
38
	private $server;
39
40
	/** @var ISearchBackend */
41
	private $searchBackend;
42
43
	/** @var QueryParser */
44
	private $queryParser;
45
46
	/** @var PathHelper */
47
	private $pathHelper;
48
49
	/** @var SearchHandler */
50
	private $search;
51
52
	/** @var DiscoverHandler */
53
	private $discover;
54
55
	public function __construct(ISearchBackend $searchBackend) {
56
		$this->searchBackend = $searchBackend;
57
		$this->queryParser = new QueryParser();
58
	}
59
60
	public function initialize(Server $server) {
61
		$this->server = $server;
62
		$this->pathHelper = new PathHelper($server);
63
		$this->search = new SearchHandler($this->searchBackend, $this->pathHelper, $server);
64
		$this->discover = new DiscoverHandler($this->searchBackend, $this->pathHelper, $this->queryParser);
65
		$server->on('method:SEARCH', [$this, 'searchHandler']);
66
		$server->on('afterMethod:OPTIONS', [$this, 'optionHandler']);
67
		$server->on('propFind', [$this, 'propFindHandler']);
68
	}
69
70
	public function propFindHandler(PropFind $propFind, INode $node) {
0 ignored issues
show
The parameter $node is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

70
	public function propFindHandler(PropFind $propFind, /** @scrutinizer ignore-unused */ INode $node) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
71
		if ($propFind->getPath() === $this->searchBackend->getArbiterPath()) {
72
			$propFind->handle('{DAV:}supported-query-grammar-set', new SupportedQueryGrammar());
73
		}
74
	}
75
76
	/**
77
	 * SEARCH is allowed for users files
78
	 *
79
	 * @param string $uri
80
	 * @return array
81
	 */
82
	public function getHTTPMethods($uri) {
83
		$path = $this->pathHelper->getPathFromUri($uri);
84
		if ($this->searchBackend->getArbiterPath() === $path) {
85
			return ['SEARCH'];
86
		} else {
87
			return [];
88
		}
89
	}
90
91
	public function optionHandler(RequestInterface $request, ResponseInterface $response) {
92
		if ($request->getPath() === $this->searchBackend->getArbiterPath()) {
93
			$response->addHeader('DASL', '<DAV:basicsearch>');
94
		}
95
	}
96
97
	public function searchHandler(RequestInterface $request, ResponseInterface $response) {
98
		$contentType = $request->getHeader('Content-Type');
99
100
		// Currently we only support xml search queries
101
		if ((strpos($contentType, 'text/xml') === false) && (strpos($contentType, 'application/xml') === false)) {
102
			return true;
103
		}
104
105
		if ($request->getPath() !== $this->searchBackend->getArbiterPath()) {
106
			return true;
107
		}
108
109
		try {
110
			$xml = $this->queryParser->parse(
111
				$request->getBodyAsString(),
112
				$request->getUrl(),
113
				$documentType
114
			);
115
		} catch (ParseException $e) {
116
			$response->setStatus(400);
117
			$response->setBody('Parse error: ' . $e->getMessage());
118
			return false;
119
		}
120
121
		switch ($documentType) {
122
			case '{DAV:}searchrequest':
123
				return $this->search->handleSearchRequest($xml, $response);
124
			case '{DAV:}query-schema-discovery':
125
				return $this->discover->handelDiscoverRequest($xml, $request, $response);
126
			default:
127
				$response->setStatus(400);
128
				$response->setBody('Unexpected document type: ' . $documentType . ' for this Content-Type, expected {DAV:}searchrequest or {DAV:}query-schema-discovery');
129
				return false;
130
		}
131
	}
132
}
133