Completed
Pull Request — master (#4995)
by Lukas
12:44
created

remote.php ➔ handleException()   C

Complexity

Conditions 8
Paths 6

Size

Total Lines 41
Code Lines 29

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 8
eloc 29
nc 6
nop 1
dl 0
loc 41
rs 5.3846
c 0
b 0
f 0
1
<?php
2
/**
3
 * @copyright Copyright (c) 2016, ownCloud, Inc.
4
 *
5
 * @author Brice Maron <[email protected]>
6
 * @author Christopher Schäpers <[email protected]>
7
 * @author Joas Schilling <[email protected]>
8
 * @author Jörn Friedrich Dreyer <[email protected]>
9
 * @author Lukas Reschke <[email protected]>
10
 * @author Robin Appelman <[email protected]>
11
 * @author Robin McCorkell <[email protected]>
12
 * @author Thomas Müller <[email protected]>
13
 * @author Vincent Petry <[email protected]>
14
 *
15
 * @license AGPL-3.0
16
 *
17
 * This code is free software: you can redistribute it and/or modify
18
 * it under the terms of the GNU Affero General Public License, version 3,
19
 * as published by the Free Software Foundation.
20
 *
21
 * This program is distributed in the hope that it will be useful,
22
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24
 * GNU Affero General Public License for more details.
25
 *
26
 * You should have received a copy of the GNU Affero General Public License, version 3,
27
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
28
 *
29
 */
30
31
use OCA\DAV\Connector\Sabre\ExceptionLoggerPlugin;
32
use Sabre\DAV\Exception\ServiceUnavailable;
33
use Sabre\DAV\Server;
34
35
/**
36
 * Class RemoteException
37
 * Dummy exception class to be use locally to identify certain conditions
38
 * Will not be logged to avoid DoS
39
 */
40
class RemoteException extends Exception {
41
}
42
43
/**
44
 * @param Exception | Error $e
45
 */
46
function handleException($e) {
47
	$request = \OC::$server->getRequest();
48
	// in case the request content type is text/xml - we assume it's a WebDAV request
49
	$isXmlContentType = strpos($request->getHeader('Content-Type'), 'text/xml');
50
	if ($isXmlContentType === 0) {
51
		// fire up a simple server to properly process the exception
52
		$server = new Server();
53
		if (!($e instanceof RemoteException)) {
54
			// we shall not log on RemoteException
55
			$server->addPlugin(new ExceptionLoggerPlugin('webdav', \OC::$server->getLogger()));
56
		}
57
		$server->on('beforeMethod', function () use ($e) {
58
			if ($e instanceof RemoteException) {
59
				switch ($e->getCode()) {
60
					case OC_Response::STATUS_SERVICE_UNAVAILABLE:
61
						throw new ServiceUnavailable($e->getMessage());
62
					case OC_Response::STATUS_NOT_FOUND:
63
						throw new \Sabre\DAV\Exception\NotFound($e->getMessage());
64
				}
65
			}
66
			$class = get_class($e);
67
			$msg = $e->getMessage();
68
			throw new ServiceUnavailable("$class: $msg");
69
		});
70
		$server->exec();
71
	} else {
72
		$statusCode = OC_Response::STATUS_INTERNAL_SERVER_ERROR;
73
		if ($e instanceof \OC\ServiceUnavailableException ) {
74
			$statusCode = OC_Response::STATUS_SERVICE_UNAVAILABLE;
75
		}
76
		if ($e instanceof RemoteException) {
77
			// we shall not log on RemoteException
78
			OC_Response::setStatus($e->getCode());
79
			OC_Template::printErrorPage($e->getMessage());
80
		} else {
81
			\OC::$server->getLogger()->logException($e, ['app' => 'remote']);
82
			OC_Response::setStatus($statusCode);
83
			OC_Template::printExceptionErrorPage($e);
84
		}
85
	}
86
}
87
88
/**
89
 * @param $service
90
 * @return string
91
 */
92
function resolveService($service) {
93
	$services = [
94
		'webdav' => 'dav/appinfo/v1/webdav.php',
95
		'dav' => 'dav/appinfo/v2/remote.php',
96
		'caldav' => 'dav/appinfo/v1/caldav.php',
97
		'calendar' => 'dav/appinfo/v1/caldav.php',
98
		'carddav' => 'dav/appinfo/v1/carddav.php',
99
		'contacts' => 'dav/appinfo/v1/carddav.php',
100
		'files' => 'dav/appinfo/v1/webdav.php',
101
	];
102
	if (isset($services[$service])) {
103
		return $services[$service];
104
	}
105
106
	return \OC::$server->getConfig()->getAppValue('core', 'remote_' . $service);
107
}
108
109
try {
110
	require_once __DIR__ . '/lib/base.php';
111
112
	// All resources served via the DAV endpoint should have the strictest possible
113
	// policy. Exempted from this is the SabreDAV browser plugin which overwrites
114
	// this policy with a softer one if debug mode is enabled.
115
	header("Content-Security-Policy: default-src 'none';");
116
117
	if (\OCP\Util::needUpgrade()) {
118
		// since the behavior of apps or remotes are unpredictable during
119
		// an upgrade, return a 503 directly
120
		throw new RemoteException('Service unavailable', OC_Response::STATUS_SERVICE_UNAVAILABLE);
121
	}
122
123
	$request = \OC::$server->getRequest();
124
	$pathInfo = $request->getPathInfo();
125
	if ($pathInfo === false || $pathInfo === '') {
126
		throw new RemoteException('Path not found', OC_Response::STATUS_NOT_FOUND);
127
	}
128
	if (!$pos = strpos($pathInfo, '/', 1)) {
129
		$pos = strlen($pathInfo);
130
	}
131
	$service=substr($pathInfo, 1, $pos-1);
132
133
	$file = resolveService($service);
134
135
	if(is_null($file)) {
136
		throw new RemoteException('Path not found', OC_Response::STATUS_NOT_FOUND);
137
	}
138
139
	$file=ltrim($file, '/');
140
141
	$parts=explode('/', $file, 2);
142
	$app=$parts[0];
143
144
	// Load all required applications
145
	\OC::$REQUESTEDAPP = $app;
146
	OC_App::loadApps(array('authentication'));
147
	OC_App::loadApps(array('filesystem', 'logging'));
148
149
	switch ($app) {
150
		case 'core':
151
			$file =  OC::$SERVERROOT .'/'. $file;
152
			break;
153
		default:
154
			if (!\OC::$server->getAppManager()->isInstalled($app)) {
155
				throw new RemoteException('App not installed: ' . $app);
156
			}
157
			OC_App::loadApp($app);
158
			$file = OC_App::getAppPath($app) .'/'. $parts[1];
159
			break;
160
	}
161
	$baseuri = OC::$WEBROOT . '/remote.php/'.$service.'/';
162
	require_once $file;
163
164
} catch (Exception $ex) {
165
	handleException($ex);
166
} catch (Error $e) {
0 ignored issues
show
Bug introduced by
The class Error does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
167
	handleException($e);
168
}
169