Completed
Pull Request — master (#1536)
by
unknown
12:42
created

AccountsController   A

Complexity

Total Complexity 33

Size/Duplication

Total Lines 358
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 12

Test Coverage

Coverage 26.35%

Importance

Changes 3
Bugs 0 Features 2
Metric Value
wmc 33
c 3
b 0
f 2
lcom 1
cbo 12
dl 0
loc 358
ccs 44
cts 167
cp 0.2635
rs 9.3999

8 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 21 1
A index() 0 10 2
A show() 0 9 2
A update() 0 5 1
A destroy() 0 9 2
B create() 0 60 4
F send() 0 85 15
B draft() 0 44 6
1
<?php
2
/**
3
 * @author Christoph Wurst <[email protected]>
4
 * @author Christoph Wurst <[email protected]>
5
 * @author Jan-Christoph Borchardt <[email protected]>
6
 * @author Lukas Reschke <[email protected]>
7
 * @author Robin McCorkell <[email protected]>
8
 * @author Thomas Müller <[email protected]>
9
 *
10
 * ownCloud - Mail
11
 *
12
 * This code is free software: you can redistribute it and/or modify
13
 * it under the terms of the GNU Affero General Public License, version 3,
14
 * as published by the Free Software Foundation.
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, version 3,
22
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
23
 *
24
 */
25
26
namespace OCA\Mail\Controller;
27
28
use Exception;
29
use Horde_Exception;
30
use Horde_Imap_Client;
31
use OCA\Mail\Account;
32
use OCA\Mail\Db\MailAccount;
33
use OCA\Mail\Model\Message;
34
use OCA\Mail\Model\ReplyMessage;
35
use OCA\Mail\Service\AccountService;
36
use OCA\Mail\Service\AutoCompletion\AddressCollector;
37
use OCA\Mail\Service\AutoConfig\AutoConfig;
38
use OCA\Mail\Service\Logger;
39
use OCA\Mail\Service\UnifiedAccount;
40
use OCP\AppFramework\Controller;
41
use OCP\AppFramework\Db\DoesNotExistException;
42
use OCP\AppFramework\Http;
43
use OCP\AppFramework\Http\JSONResponse;
44
use OCP\AppFramework\Http\Response;
45
use OCP\Files\File;
46
use OCP\Files\Folder;
47
use OCP\IL10N;
48
use OCP\IRequest;
49
use OCP\Security\ICrypto;
50
51
class AccountsController extends Controller {
52
53
	/** @var AccountService */
54
	private $accountService;
55
56
	/** @var string */
57
	private $currentUserId;
58
59
	/** @var AutoConfig */
60
	private $autoConfig;
61
62
	/** @var Folder */
63
	private $userFolder;
64
65
	/** @var Logger */
66
	private $logger;
67
68
	/** @var IL10N */
69
	private $l10n;
70
71
	/** @var ICrypto */
72
	private $crypto;
73
74
	/** @var AddressCollector  */
75
	private $addressCollector;
76
77
	/**
78
	 * @param string $appName
79
	 * @param IRequest $request
80
	 * @param AccountService $accountService
81
	 * @param $UserId
82
	 * @param $userFolder
83
	 * @param AutoConfig $autoConfig
84
	 * @param Logger $logger
85
	 * @param IL10N $l10n
86
	 * @param ICrypto $crypto
87
	 */
88 15
	public function __construct($appName,
89
		IRequest $request,
90
		AccountService $accountService,
91
		$UserId,
92
		$userFolder,
93
		AutoConfig $autoConfig,
94
		Logger $logger,
95
		IL10N $l10n,
96
		ICrypto $crypto,
97
		AddressCollector $addressCollector
98
	) {
99 15
		parent::__construct($appName, $request);
100 15
		$this->accountService = $accountService;
101 15
		$this->currentUserId = $UserId;
102 15
		$this->userFolder = $userFolder;
103 15
		$this->autoConfig = $autoConfig;
104 15
		$this->logger = $logger;
105 15
		$this->l10n = $l10n;
106 15
		$this->crypto = $crypto;
107 15
		$this->addressCollector = $addressCollector;
108 15
	}
109
110
	/**
111
	 * @NoAdminRequired
112
	 * @NoCSRFRequired
113
	 *
114
	 * @return JSONResponse
115
	 */
116 1
	public function index() {
117 1
		$mailAccounts = $this->accountService->findByUserId($this->currentUserId);
118
119 1
		$json = [];
120 1
		foreach ($mailAccounts as $mailAccount) {
121 1
			$json[] = $mailAccount->getConfiguration();
122 1
		}
123
124 1
		return new JSONResponse($json);
125
	}
126
127
	/**
128
	 * @NoAdminRequired
129
	 *
130
	 * @param int $accountId
131
	 * @return JSONResponse
132
	 */
133 2
	public function show($accountId) {
134
		try {
135 2
			$account = $this->accountService->find($this->currentUserId, $accountId);
136
137 2
			return new JSONResponse($account->getConfiguration());
138 1
		} catch (DoesNotExistException $e) {
0 ignored issues
show
Bug introduced by
The class OCP\AppFramework\Db\DoesNotExistException 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...
139 1
			return new JSONResponse([], 404);
140
		}
141
	}
142
143
	/**
144
	 * @NoAdminRequired
145
	 */
146
	public function update() {
147
		$response = new Response();
148
		$response->setStatus(Http::STATUS_NOT_IMPLEMENTED);
149
		return $response;
150
	}
151
152
	/**
153
	 * @NoAdminRequired
154
	 *
155
	 * @param int $accountId
156
	 * @return JSONResponse
157
	 */
158 2
	public function destroy($accountId) {
159
		try {
160 2
			$this->accountService->delete($this->currentUserId, $accountId);
161
162 1
			return new JSONResponse();
163 1
		} catch (DoesNotExistException $e) {
0 ignored issues
show
Bug introduced by
The class OCP\AppFramework\Db\DoesNotExistException 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...
164 1
			return new JSONResponse();
165
		}
166
	}
167
168
	/**
169
	 * @NoAdminRequired
170
	 *
171
	 * @param string $accountName
172
	 * @param string $emailAddress
173
	 * @param string $password
174
	 * @param string $imapHost
175
	 * @param int $imapPort
176
	 * @param string $imapSslMode
177
	 * @param string $imapUser
178
	 * @param string $imapPassword
179
	 * @param string $smtpHost
180
	 * @param int $smtpPort
181
	 * @param string $smtpSslMode
182
	 * @param string $smtpUser
183
	 * @param string $smtpPassword
184
	 * @param bool $autoDetect
185
	 * @return JSONResponse
186
	 */
187 2
	public function create($accountName, $emailAddress, $password,
188
		$imapHost, $imapPort, $imapSslMode, $imapUser, $imapPassword,
189
		$smtpHost, $smtpPort, $smtpSslMode, $smtpUser, $smtpPassword,
190
		$autoDetect) {
191
		try {
192 2
			if ($autoDetect) {
193 2
				$this->logger->info('setting up auto detected account');
194 2
				$newAccount = $this->autoConfig->createAutoDetected($emailAddress, $password, $accountName);
195 2
			} else {
196
				$this->logger->info('Setting up manually configured account');
197
				$newAccount = new MailAccount([
198
					'accountName'  => $accountName,
199
					'emailAddress' => $emailAddress,
200
					'imapHost'     => $imapHost,
201
					'imapPort'     => $imapPort,
202
					'imapSslMode'  => $imapSslMode,
203
					'imapUser'     => $imapUser,
204
					'imapPassword' => $imapPassword,
205
					'smtpHost'     => $smtpHost,
206
					'smtpPort'     => $smtpPort,
207
					'smtpSslMode'  => $smtpSslMode,
208
					'smtpUser'     => $smtpUser,
209
					'smtpPassword' => $smtpPassword
210
				]);
211
				$newAccount->setUserId($this->currentUserId);
212
				$newAccount->setInboundPassword(
213
					$this->crypto->encrypt(
214
						$newAccount->getInboundPassword()
215
					)
216
				);
217
				$newAccount->setOutboundPassword(
218
					$this->crypto->encrypt(
219
						$newAccount->getOutboundPassword()
220
					)
221
				);
222
223
				$a = new Account($newAccount);
224
				$this->logger->debug('Connecting to account {account}', ['account' => $newAccount->getEmail()]);
225
				$a->testConnectivity();
226
			}
227
228 2
			if ($newAccount) {
229 1
				$this->accountService->save($newAccount);
230 1
				$this->logger->debug("account created " . $newAccount->getId());
231 1
				return new JSONResponse(
232 1
					['data' => ['id' => $newAccount->getId()]],
233 1
					Http::STATUS_CREATED);
234
			}
235 1
		} catch (Exception $ex) {
236
			$this->logger->error('Creating account failed: ' . $ex->getMessage());
237
			return new JSONResponse(
238
				array('message' => $this->l10n->t('Creating account failed: ') . $ex->getMessage()),
239
				HTTP::STATUS_BAD_REQUEST);
240
		}
241
242 1
		$this->logger->info('Auto detect failed');
243 1
		return new JSONResponse(
244 1
			array('message' => $this->l10n->t('Auto detect failed. Please use manual mode.')),
245 1
			HTTP::STATUS_BAD_REQUEST);
246
	}
247
248
	/**
249
	 * @NoAdminRequired
250
	 *
251
	 * @param int $accountId
252
	 * @param string $folderId
253
	 * @param string $subject
254
	 * @param string $body
255
	 * @param string $to
256
	 * @param string $cc
257
	 * @param string $bcc
258
	 * @param int $draftUID
259
	 * @param string $messageId
260
	 * @param mixed $attachments
261
	 * @param string $type
262
	 * @return JSONResponse
263
	 */
264
	public function send($accountId, $folderId, $subject, $body, $to, $cc,
265
		$bcc, $draftUID, $messageId, $attachments,$type) {
266
		$account = $this->accountService->find($this->currentUserId, $accountId);
267
		if ($account instanceof UnifiedAccount) {
268
			list($account, $folderId, $messageId) = $account->resolve($messageId);
269
		}
270
		if (!$account instanceof Account) {
271
			return new JSONResponse(
272
				['message' => 'Invalid account'],
273
				Http::STATUS_BAD_REQUEST
274
			);
275
		}
276
277
		$mailbox = null;
278
		if (!is_null($folderId) && !is_null($messageId)) {
279
			// Reply
280
			$message = $account->newReplyMessage();
281
282
			$mailbox = $account->getMailbox(base64_decode($folderId));
283
			$repliedMessage = $mailbox->getMessage($messageId);
284
285
			if (is_null($subject)) {
286
				// No subject set – use the original one
287
				$message->setSubject($repliedMessage->getSubject());
288
			} else {
289
				$message->setSubject($subject);
290
			}
291
292
			if (is_null($to)) {
293
				$message->setTo(Message::parseAddressList($repliedMessage->getToList()));
0 ignored issues
show
Documentation introduced by
$repliedMessage->getToList() is of type array, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
294
			} else {
295
				$message->setTo(Message::parseAddressList($to));
296
			}
297
298
			$message->setRepliedMessage($repliedMessage);
299
		} else {
300
			// New message
301
			$message = $account->newMessage();
302
			$message->setTo(Message::parseAddressList($to));
303
			$message->setSubject($subject ? : '');
304
		}
305
306
		$message->setFrom($account->getEMailAddress());
307
		$message->setCC(Message::parseAddressList($cc));
308
		$message->setBcc(Message::parseAddressList($bcc));
309
		$message->setContent($body);
310
		$message->setType($type);
311
312
		if (is_array($attachments)) {
313
			foreach($attachments as $attachment) {
314
				$fileName = $attachment['fileName'];
315
				if ($this->userFolder->nodeExists($fileName)) {
316
					$f = $this->userFolder->get($fileName);
317
					if ($f instanceof File) {
0 ignored issues
show
Bug introduced by
The class OCP\Files\File does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
318
						$message->addAttachmentFromFiles($f);
319
					}
320
				}
321
			}
322
		}
323
324
		try {
325
			$account->sendMessage($message, $draftUID);
326
327
			// in case of reply we flag the message as answered
328
			if ($message instanceof ReplyMessage) {
329
				$mailbox->setMessageFlag($messageId, Horde_Imap_Client::FLAG_ANSWERED, true);
330
			}
331
332
			// Collect mail addresses
333
			try {
334
				$addresses = array_merge($message->getToList(), $message->getCCList(), $message->getBCCList());
335
				$this->addressCollector->addAddresses($addresses);
336
			} catch (Exception $e) {
337
				$this->logger->error("Error while collecting mail addresses: " . $e->getMessage());
338
			}
339
		} catch (Horde_Exception $ex) {
0 ignored issues
show
Bug introduced by
The class Horde_Exception does not exist. Is this class maybe located in a folder that is not analyzed, or in a newer version of your dependencies than listed in your composer.lock/composer.json?
Loading history...
340
			$this->logger->error('Sending mail failed: ' . $ex->getMessage());
341
			return new JSONResponse(
342
				array('message' => $ex->getMessage()),
343
				Http::STATUS_INTERNAL_SERVER_ERROR
344
			);
345
		}
346
347
		return new JSONResponse();
348
	}
349
350
	/**
351
	 * @NoAdminRequired
352
	 *
353
	 * @param int $accountId
354
	 * @param string $subject
355
	 * @param string $body
356
	 * @param string $to
357
	 * @param string $cc
358
	 * @param string $bcc
359
	 * @param int $uid
360
	 * @param string $messageId
361
	 * @return JSONResponse
362
	 */
363
	public function draft($accountId, $subject, $body, $to, $cc, $bcc, $uid, $messageId,$type) {
364
		if (is_null($uid)) {
365
			$this->logger->info("Saving a new draft in account <$accountId>");
366
		} else {
367
			$this->logger->info("Updating draft <$uid> in account <$accountId>");
368
		}
369
370
		$account = $this->accountService->find($this->currentUserId, $accountId);
371
		if ($account instanceof UnifiedAccount) {
372
			list($account) = $account->resolve($messageId);
373
		}
374
		if (!$account instanceof Account) {
375
			return new JSONResponse(
376
				array('message' => 'Invalid account'),
377
				Http::STATUS_BAD_REQUEST
378
			);
379
		}
380
381
		$message = $account->newMessage();
382
		$message->setTo(Message::parseAddressList($to));
383
		$message->setSubject($subject ? : '');
384
		$message->setFrom($account->getEMailAddress());
385
		$message->setCC(Message::parseAddressList($cc));
386
		$message->setBcc(Message::parseAddressList($bcc));
387
		$message->setContent($body);
388
		$message->setType($type);
389
390
		// create transport and save message
391
		try {
392
			$newUID = $account->saveDraft($message, $uid);
393
		} catch (Horde_Exception $ex) {
0 ignored issues
show
Bug introduced by
The class Horde_Exception does not exist. Is this class maybe located in a folder that is not analyzed, or in a newer version of your dependencies than listed in your composer.lock/composer.json?
Loading history...
394
			$this->logger->error('Saving draft failed: ' . $ex->getMessage());
395
			return new JSONResponse(
396
				[
397
					'message' => $ex->getMessage()
398
				],
399
				Http::STATUS_INTERNAL_SERVER_ERROR
400
			);
401
		}
402
403
		return new JSONResponse([
404
			'uid' => $newUID
405
		]);
406
	}
407
408
}
409