Passed
Push — master ( b8b2e7...0ab5b3 )
by Blizzz
23:57 queued 11s
created

OCSMiddleware::afterController()   B

Complexity

Conditions 7
Paths 6

Size

Total Lines 27
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 12
nc 6
nop 3
dl 0
loc 27
rs 8.8333
c 0
b 0
f 0
1
<?php
2
/**
3
 *
4
 *
5
 * @author Christoph Wurst <[email protected]>
6
 * @author Lukas Reschke <[email protected]>
7
 * @author Roeland Jago Douma <[email protected]>
8
 *
9
 * @license GNU AGPL version 3 or any later version
10
 *
11
 * This program is free software: you can redistribute it and/or modify
12
 * it under the terms of the GNU Affero General Public License as
13
 * published by the Free Software Foundation, either version 3 of the
14
 * License, or (at your option) any later version.
15
 *
16
 * This program is distributed in the hope that it will be useful,
17
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
 * GNU Affero General Public License for more details.
20
 *
21
 * You should have received a copy of the GNU Affero General Public License
22
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
23
 *
24
 */
25
26
namespace OC\AppFramework\Middleware;
27
28
use OC\AppFramework\Http;
29
use OC\AppFramework\OCS\BaseResponse;
30
use OC\AppFramework\OCS\V1Response;
31
use OC\AppFramework\OCS\V2Response;
32
use OCP\AppFramework\Controller;
33
use OCP\AppFramework\Http\DataResponse;
34
use OCP\AppFramework\Http\JSONResponse;
35
use OCP\AppFramework\Http\Response;
36
use OCP\AppFramework\Middleware;
37
use OCP\AppFramework\OCS\OCSException;
38
use OCP\AppFramework\OCSController;
39
use OCP\IRequest;
40
41
class OCSMiddleware extends Middleware {
42
43
	/** @var IRequest */
44
	private $request;
45
46
	/** @var int */
47
	private $ocsVersion;
48
49
	/**
50
	 * @param IRequest $request
51
	 */
52
	public function __construct(IRequest $request) {
53
		$this->request = $request;
54
	}
55
56
	/**
57
	 * @param Controller $controller
58
	 * @param string $methodName
59
	 */
60
	public function beforeController($controller, $methodName) {
61
		if ($controller instanceof OCSController) {
62
			if (substr_compare($this->request->getScriptName(), '/ocs/v2.php', -strlen('/ocs/v2.php')) === 0) {
63
				$this->ocsVersion = 2;
64
			} else {
65
				$this->ocsVersion = 1;
66
			}
67
			$controller->setOCSVersion($this->ocsVersion);
68
		}
69
	}
70
71
	/**
72
	 * @param Controller $controller
73
	 * @param string $methodName
74
	 * @param \Exception $exception
75
	 * @throws \Exception
76
	 * @return BaseResponse
77
	 */
78
	public function afterException($controller, $methodName, \Exception $exception) {
79
		if ($controller instanceof OCSController && $exception instanceof OCSException) {
80
			$code = $exception->getCode();
81
			if ($code === 0) {
82
				$code = \OCP\AppFramework\OCSController::RESPOND_UNKNOWN_ERROR;
83
			}
84
85
			return $this->buildNewResponse($controller, $code, $exception->getMessage());
86
		}
87
88
		throw $exception;
89
	}
90
91
	/**
92
	 * @param Controller $controller
93
	 * @param string $methodName
94
	 * @param Response $response
95
	 * @return \OCP\AppFramework\Http\Response
96
	 */
97
	public function afterController($controller, $methodName, Response $response) {
98
		/*
99
		 * If a different middleware has detected that a request unauthorized or forbidden
100
		 * we need to catch the response and convert it to a proper OCS response.
101
		 */
102
		if ($controller instanceof OCSController && !($response instanceof BaseResponse)) {
103
			if ($response->getStatus() === Http::STATUS_UNAUTHORIZED) {
104
				$message = '';
105
				if ($response instanceof JSONResponse) {
106
					/** @var DataResponse $response */
107
					$message = $response->getData()['message'];
108
				}
109
110
				return $this->buildNewResponse($controller, OCSController::RESPOND_UNAUTHORISED, $message);
111
			}
112
			if ($response->getStatus() === Http::STATUS_FORBIDDEN) {
113
				$message = '';
114
				if ($response instanceof JSONResponse) {
115
					/** @var DataResponse $response */
116
					$message = $response->getData()['message'];
117
				}
118
119
				return $this->buildNewResponse($controller, Http::STATUS_FORBIDDEN, $message);
120
			}
121
		}
122
123
		return $response;
124
	}
125
126
	/**
127
	 * @param Controller $controller
128
	 * @param int $code
129
	 * @param string $message
130
	 * @return V1Response|V2Response
131
	 */
132
	private function buildNewResponse(Controller $controller, $code, $message) {
133
		$format = $this->getFormat($controller);
134
135
		$data = new DataResponse();
136
		$data->setStatus($code);
137
		if ($this->ocsVersion === 1) {
138
			$response = new V1Response($data, $format, $message);
139
		} else {
140
			$response = new V2Response($data, $format, $message);
141
		}
142
143
		return $response;
144
	}
145
146
	/**
147
	 * @param Controller $controller
148
	 * @return string
149
	 */
150
	private function getFormat(Controller $controller) {
151
		// get format from the url format or request format parameter
152
		$format = $this->request->getParam('format');
153
154
		// if none is given try the first Accept header
155
		if ($format === null) {
156
			$headers = $this->request->getHeader('Accept');
157
			$format = $controller->getResponderByHTTPHeader($headers, 'xml');
158
		}
159
160
		return $format;
161
	}
162
}
163