Passed
Push — master ( 54a973...87c8a7 )
by Morris
11:42 queued 10s
created

AppleProvisioningPlugin::httpGet()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 82
Code Lines 60

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 60
nc 5
nop 2
dl 0
loc 82
rs 8.5616
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * @copyright 2018, Georg Ehrke <[email protected]>
4
 *
5
 * @author Georg Ehrke <[email protected]>
6
 *
7
 * @license GNU AGPL version 3 or any later version
8
 *
9
 * This program is free software: you can redistribute it and/or modify
10
 * it under the terms of the GNU Affero General Public License as
11
 * published by the Free Software Foundation, either version 3 of the
12
 * License, or (at your option) any later version.
13
 *
14
 * This program is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 * GNU Affero General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU Affero General Public License
20
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
21
 *
22
 */
23
24
namespace OCA\DAV\Provisioning\Apple;
25
26
use OCP\IL10N;
27
use OCP\IRequest;
28
use OCP\IURLGenerator;
29
use OCP\IUserSession;
30
use Sabre\DAV\Server;
31
use Sabre\DAV\ServerPlugin;
32
use Sabre\HTTP\RequestInterface;
33
use Sabre\HTTP\ResponseInterface;
34
35
class AppleProvisioningPlugin extends ServerPlugin {
36
37
	/**
38
	 * @var Server
39
	 */
40
	protected $server;
41
42
	/**
43
	 * @var IURLGenerator
44
	 */
45
	protected $urlGenerator;
46
47
	/**
48
	 * @var IUserSession
49
	 */
50
	protected $userSession;
51
52
	/**
53
	 * @var \OC_Defaults
54
	 */
55
	protected $themingDefaults;
56
57
	/**
58
	 * @var IRequest
59
	 */
60
	protected $request;
61
62
	/**
63
	 * @var IL10N
64
	 */
65
	protected $l10n;
66
67
	/**
68
	 * @var \closure
69
	 */
70
	protected $uuidClosure;
71
72
	/**
73
	 * AppleProvisioningPlugin constructor.
74
	 *
75
	 * @param IUserSession $userSession
76
	 * @param IURLGenerator $urlGenerator
77
	 * @param \OC_Defaults $themingDefaults
78
	 * @param IRequest $request
79
	 * @param IL10N $l10n
80
	 * @param \closure $uuidClosure
81
	 */
82
	public function __construct(IUserSession $userSession, IURLGenerator $urlGenerator,
83
								\OC_Defaults $themingDefaults, IRequest $request,
84
								IL10N $l10n, \closure $uuidClosure) {
85
		$this->userSession = $userSession;
86
		$this->urlGenerator = $urlGenerator;
87
		$this->themingDefaults = $themingDefaults;
88
		$this->request = $request;
89
		$this->l10n = $l10n;
90
		$this->uuidClosure = $uuidClosure;
91
	}
92
93
	/**
94
	 * @param Server $server
95
	 */
96
	public function initialize(Server $server) {
97
		$this->server = $server;
98
		$this->server->on('method:GET', [$this, 'httpGet'], 90);
99
	}
100
101
	/**
102
	 * @param RequestInterface $request
103
	 * @param ResponseInterface $response
104
	 * @return boolean
105
	 */
106
	public function httpGet(RequestInterface $request, ResponseInterface $response):bool {
107
		if ($request->getPath() !== 'provisioning/' . AppleProvisioningNode::FILENAME) {
108
			return true;
109
		}
110
111
		$user = $this->userSession->getUser();
112
		if (!$user) {
113
			return true;
114
		}
115
116
		$serverProtocol = $this->request->getServerProtocol();
117
		$useSSL = ($serverProtocol === 'https');
118
119
		if (!$useSSL) {
120
			$response->setStatus(200);
121
			$response->setHeader('Content-Type', 'text/plain; charset=utf-8');
122
			$response->setBody($this->l10n->t('Your %s needs to be configured to use HTTPS in order to use CalDAV and CardDAV with iOS/macOS.', [$this->themingDefaults->getName()]));
123
124
			return false;
125
		}
126
127
		$absoluteURL = $request->getAbsoluteUrl();
128
		$parsedUrl = parse_url($absoluteURL);
129
		if (isset($parsedUrl['port'])) {
130
			$serverPort = (int) $parsedUrl['port'];
131
		} else {
132
			$serverPort = 443;
133
		}
134
		$server_url = $parsedUrl['host'];
135
136
		$description = $this->themingDefaults->getName();
137
		$userId = $user->getUID();
138
139
		$reverseDomain = implode('.', array_reverse(explode('.', $parsedUrl['host'])));
140
141
		$caldavUUID = call_user_func($this->uuidClosure);
142
		$carddavUUID = call_user_func($this->uuidClosure);
143
		$profileUUID = call_user_func($this->uuidClosure);
144
145
		$caldavIdentifier = $reverseDomain . '.' . $caldavUUID;
146
		$carddavIdentifier = $reverseDomain . '.' . $carddavUUID;
147
		$profileIdentifier = $reverseDomain . '.' . $profileUUID;
148
149
		$caldavDescription = $this->l10n->t('Configures a CalDAV account');
150
		$caldavDisplayname = $description . ' CalDAV';
151
		$carddavDescription = $this->l10n->t('Configures a CardDAV account');
152
		$carddavDisplayname = $description . ' CardDAV';
153
154
		$filename = $userId . '-' . AppleProvisioningNode::FILENAME;
155
156
		$xmlSkeleton = $this->getTemplate();
157
		$body = vsprintf($xmlSkeleton, array_map(function($v) {
158
				return \htmlspecialchars($v, ENT_XML1, 'UTF-8');
159
			}, [
160
				$description,
161
				$server_url,
162
				$userId,
163
				$serverPort,
164
				$caldavDescription,
165
				$caldavDisplayname,
166
				$caldavIdentifier,
167
				$caldavUUID,
168
				$description,
169
				$server_url,
170
				$userId,
171
				$serverPort,
172
				$carddavDescription,
173
				$carddavDisplayname,
174
				$carddavIdentifier,
175
				$carddavUUID,
176
				$description,
177
				$profileIdentifier,
178
				$profileUUID
179
			]
180
		));
181
182
		$response->setStatus(200);
183
		$response->setHeader('Content-Disposition', 'attachment; filename="' . $filename . '"');
184
		$response->setHeader('Content-Type', 'application/xml; charset=utf-8');
185
		$response->setBody($body);
186
187
		return false;
188
	}
189
190
	/**
191
	 * @return string
192
	 */
193
	private function getTemplate():string {
194
		return <<<EOF
195
<?xml version="1.0" encoding="UTF-8"?>
196
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
197
<plist version="1.0">
198
<dict>
199
	<key>PayloadContent</key>
200
	<array>
201
		<dict>
202
			<key>CalDAVAccountDescription</key>
203
			<string>%s</string>
204
			<key>CalDAVHostName</key>
205
			<string>%s</string>
206
			<key>CalDAVUsername</key>
207
			<string>%s</string>
208
			<key>CalDAVUseSSL</key>
209
			<true/>
210
			<key>CalDAVPort</key>
211
			<integer>%s</integer>
212
			<key>PayloadDescription</key>
213
			<string>%s</string>
214
			<key>PayloadDisplayName</key>
215
			<string>%s</string>
216
			<key>PayloadIdentifier</key>
217
			<string>%s</string>
218
			<key>PayloadType</key>
219
			<string>com.apple.caldav.account</string>
220
			<key>PayloadUUID</key>
221
			<string>%s</string>
222
			<key>PayloadVersion</key>
223
			<integer>1</integer>
224
		</dict>
225
		<dict>
226
			<key>CardDAVAccountDescription</key>
227
			<string>%s</string>
228
			<key>CardDAVHostName</key>
229
			<string>%s</string>
230
			<key>CardDAVUsername</key>
231
			<string>%s</string>
232
			<key>CardDAVUseSSL</key>
233
			<true/>
234
			<key>CardDAVPort</key>
235
			<integer>%s</integer>
236
			<key>PayloadDescription</key>
237
			<string>%s</string>
238
			<key>PayloadDisplayName</key>
239
			<string>%s</string>
240
			<key>PayloadIdentifier</key>
241
			<string>%s</string>
242
			<key>PayloadType</key>
243
			<string>com.apple.carddav.account</string>
244
			<key>PayloadUUID</key>
245
			<string>%s</string>
246
			<key>PayloadVersion</key>
247
			<integer>1</integer>
248
		</dict>
249
	</array>
250
	<key>PayloadDisplayName</key>
251
	<string>%s</string>
252
	<key>PayloadIdentifier</key>
253
	<string>%s</string>
254
	<key>PayloadRemovalDisallowed</key>
255
	<false/>
256
	<key>PayloadType</key>
257
	<string>Configuration</string>
258
	<key>PayloadUUID</key>
259
	<string>%s</string>
260
	<key>PayloadVersion</key>
261
	<integer>1</integer>
262
</dict>
263
</plist>
264
265
EOF;
266
	}
267
}
268