Completed
Pull Request — master (#1433)
by Christoph
35:09
created

AccountsController::destroy()   A

Complexity

Conditions 2
Paths 3

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2
Metric Value
dl 0
loc 9
ccs 5
cts 5
cp 1
rs 9.6666
cc 2
eloc 6
nc 3
nop 1
crap 2
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\ILogger;
49
use OCP\IRequest;
50
use OCP\Security\ICrypto;
51
52
class AccountsController extends Controller {
53
54
	/** @var AccountService */
55
	private $accountService;
56
57
	/** @var string */
58
	private $currentUserId;
59
60
	/** @var AutoConfig */
61
	private $autoConfig;
62
63
	/** @var Folder */
64
	private $userFolder;
65
66
	/** @var ILogger */
67
	private $logger;
68
69
	/** @var IL10N */
70
	private $l10n;
71
72
	/** @var ICrypto */
73
	private $crypto;
74
75
	/** @var AddressCollector  */
76
	private $addressCollector;
77
78
	/**
79
	 * @param string $appName
80
	 * @param IRequest $request
81
	 * @param AccountService $accountService
82
	 * @param $UserId
83
	 * @param $userFolder
84
	 * @param AutoConfig $autoConfig
85
	 * @param Logger $logger
86
	 * @param IL10N $l10n
87
	 * @param ICrypto $crypto
88
	 */
89 15
	public function __construct($appName,
90
		IRequest $request,
91
		AccountService $accountService,
92
		$UserId,
93
		$userFolder,
94
		AutoConfig $autoConfig,
95
		Logger $logger,
96
		IL10N $l10n,
97
		ICrypto $crypto,
98
		AddressCollector $addressCollector
99
	) {
100 15
		parent::__construct($appName, $request);
101 15
		$this->accountService = $accountService;
102 15
		$this->currentUserId = $UserId;
103 15
		$this->userFolder = $userFolder;
104 15
		$this->autoConfig = $autoConfig;
105 15
		$this->logger = $logger;
106 15
		$this->l10n = $l10n;
107 15
		$this->crypto = $crypto;
108 15
		$this->addressCollector = $addressCollector;
109 15
	}
110
111
	/**
112
	 * @NoAdminRequired
113
	 * @NoCSRFRequired
114
	 *
115
	 * @return JSONResponse
116
	 */
117 1
	public function index() {
118 1
		$mailAccounts = $this->accountService->findByUserId($this->currentUserId);
119
120 1
		$json = [];
121 1
		foreach ($mailAccounts as $mailAccount) {
122 1
			$json[] = $mailAccount->getConfiguration();
123 1
		}
124
125 1
		return new JSONResponse($json);
126
	}
127
128
	/**
129
	 * @NoAdminRequired
130
	 *
131
	 * @param int $accountId
132
	 * @return JSONResponse
133
	 */
134 2
	public function show($accountId) {
135
		try {
136 2
			$account = $this->accountService->find($this->currentUserId, $accountId);
137
138 2
			return new JSONResponse($account->getConfiguration());
139 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...
140 1
			return new JSONResponse([], 404);
141
		}
142
	}
143
144
	/**
145
	 * @NoAdminRequired
146
	 */
147
	public function update() {
148
		$response = new Response();
149
		$response->setStatus(Http::STATUS_NOT_IMPLEMENTED);
150
		return $response;
151
	}
152
153
	/**
154
	 * @NoAdminRequired
155
	 *
156
	 * @param int $accountId
157
	 * @return JSONResponse
158
	 */
159 2
	public function destroy($accountId) {
160
		try {
161 2
			$this->accountService->delete($this->currentUserId, $accountId);
162
163 1
			return new JSONResponse();
164 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...
165 1
			return new JSONResponse();
166
		}
167
	}
168
169
	/**
170
	 * @NoAdminRequired
171
	 *
172
	 * @param string $accountName
173
	 * @param string $emailAddress
174
	 * @param string $password
175
	 * @param string $imapHost
176
	 * @param int $imapPort
177
	 * @param string $imapSslMode
178
	 * @param string $imapUser
179
	 * @param string $imapPassword
180
	 * @param string $smtpHost
181
	 * @param int $smtpPort
182
	 * @param string $smtpSslMode
183
	 * @param string $smtpUser
184
	 * @param string $smtpPassword
185
	 * @param bool $autoDetect
186
	 * @return JSONResponse
187
	 */
188 2
	public function create($accountName, $emailAddress, $password,
189
		$imapHost, $imapPort, $imapSslMode, $imapUser, $imapPassword,
190
		$smtpHost, $smtpPort, $smtpSslMode, $smtpUser, $smtpPassword,
191
		$autoDetect) {
192
		try {
193 2
			if ($autoDetect) {
194 2
				$this->logger->info('setting up auto detected account');
195 2
				$newAccount = $this->autoConfig->createAutoDetected($emailAddress, $password, $accountName);
196 2
			} else {
197
				$this->logger->info('Setting up manually configured account');
198
				$newAccount = new MailAccount([
199
					'accountName'  => $accountName,
200
					'emailAddress' => $emailAddress,
201
					'imapHost'     => $imapHost,
202
					'imapPort'     => $imapPort,
203
					'imapSslMode'  => $imapSslMode,
204
					'imapUser'     => $imapUser,
205
					'imapPassword' => $imapPassword,
206
					'smtpHost'     => $smtpHost,
207
					'smtpPort'     => $smtpPort,
208
					'smtpSslMode'  => $smtpSslMode,
209
					'smtpUser'     => $smtpUser,
210
					'smtpPassword' => $smtpPassword
211
				]);
212
				$newAccount->setUserId($this->currentUserId);
213
				$newAccount->setInboundPassword(
214
					$this->crypto->encrypt(
215
						$newAccount->getInboundPassword()
216
					)
217
				);
218
				$newAccount->setOutboundPassword(
219
					$this->crypto->encrypt(
220
						$newAccount->getOutboundPassword()
221
					)
222
				);
223
224
				$a = new Account($newAccount);
225
				$this->logger->debug('Connecting to account {account}', ['account' => $newAccount->getEmail()]);
226
				$a->testConnectivity();
227
			}
228
229 2
			if ($newAccount) {
230 1
				$this->accountService->save($newAccount);
231 1
				$this->logger->debug("account created " . $newAccount->getId());
232 1
				return new JSONResponse(
233 1
					['data' => ['id' => $newAccount->getId()]],
234 1
					Http::STATUS_CREATED);
235
			}
236 1
		} catch (\Exception $ex) {
237
			$this->logger->error('Creating account failed: ' . $ex->getMessage());
238
			return new JSONResponse(
239
				array('message' => $this->l10n->t('Creating account failed: ') . $ex->getMessage()),
240
				HTTP::STATUS_BAD_REQUEST);
241
		}
242
243 1
		$this->logger->info('Auto detect failed');
244 1
		return new JSONResponse(
245 1
			array('message' => $this->l10n->t('Auto detect failed. Please use manual mode.')),
246 1
			HTTP::STATUS_BAD_REQUEST);
247
	}
248
249
	/**
250
	 * @NoAdminRequired
251
	 *
252
	 * @param int $accountId
253
	 * @param string $folderId
254
	 * @param string $subject
255
	 * @param string $body
256
	 * @param string $to
257
	 * @param string $cc
258
	 * @param string $bcc
259
	 * @param int $draftUID
260
	 * @param string $messageId
261
	 * @param mixed $attachments
262
	 * @return JSONResponse
263
	 */
264 4
	public function send($accountId, $folderId, $subject, $body, $to, $cc,
265
		$bcc, $draftUID, $messageId, $attachments) {
266 4
		$account = $this->accountService->find($this->currentUserId, $accountId);
267 4
		if ($account instanceof UnifiedAccount) {
268 2
			list($account, $folderId, $messageId) = $account->resolve($messageId);
269 2
		}
270 4
		if (!$account instanceof Account) {
271
			return new JSONResponse(
272
				['message' => 'Invalid account'],
273
				Http::STATUS_BAD_REQUEST
274
			);
275
		}
276
277 4
		$mailbox = null;
278 4
		if (!is_null($folderId) && !is_null($messageId)) {
279
			// Reply
280 2
			$message = $account->newReplyMessage();
281
282 2
			$mailbox = $account->getMailbox(base64_decode($folderId));
283 2
			$repliedMessage = $mailbox->getMessage($messageId);
284
285 2
			if (is_null($subject)) {
286
				// No subject set – use the original one
287
				$message->setSubject($repliedMessage->getSubject());
288
			} else {
289 2
				$message->setSubject($subject);
290
			}
291
292 2
			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 2
				$message->setTo(Message::parseAddressList($to));
296
			}
297
298 2
			$message->setRepliedMessage($repliedMessage);
299 2
		} else {
300
			// New message
301 2
			$message = $account->newMessage();
302 2
			$message->setTo(Message::parseAddressList($to));
303 2
			$message->setSubject($subject ? : '');
304
		}
305
306 4
		$message->setFrom($account->getEMailAddress());
307 4
		$message->setCC(Message::parseAddressList($cc));
308 4
		$message->setBcc(Message::parseAddressList($bcc));
309 4
		$message->setContent($body);
310
311 4
		if (is_array($attachments)) {
312 4
			foreach($attachments as $attachment) {
313 4
				$fileName = $attachment['fileName'];
314 4
				if ($this->userFolder->nodeExists($fileName)) {
315 4
					$f = $this->userFolder->get($fileName);
316 4
					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...
317 4
						$message->addAttachmentFromFiles($f);
318 4
					}
319 4
				}
320 4
			}
321 4
		}
322
323
		try {
324 4
			$account->sendMessage($message, $draftUID);
325
326
			// in case of reply we flag the message as answered
327 4
			if ($message instanceof ReplyMessage) {
328 2
				$mailbox->setMessageFlag($messageId, Horde_Imap_Client::FLAG_ANSWERED, true);
329 2
			}
330
331
			// Collect mail addresses
332
			try {
333 4
				$addresses = array_merge($message->getToList(), $message->getCCList(), $message->getBCCList());
334 4
				$this->addressCollector->addAddresses($addresses);
335 4
			} catch (Exception $e) {
336 1
				$this->logger->error("Error while collecting mail addresses: " . $e->getMessage());
337
			}
338 4
		} 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...
339
			$this->logger->error('Sending mail failed: ' . $ex->getMessage());
340
			return new JSONResponse(
341
				array('message' => $ex->getMessage()),
342
				Http::STATUS_INTERNAL_SERVER_ERROR
343
			);
344
		}
345
346 4
		return new JSONResponse();
347
	}
348
349
	/**
350
	 * @NoAdminRequired
351
	 * 
352
	 * @param int $accountId
353
	 * @param string $subject
354
	 * @param string $body
355
	 * @param string $to
356
	 * @param string $cc
357
	 * @param string $bcc
358
	 * @param int $uid
359
	 * @param string $messageId
360
	 * @return JSONResponse
361
	 */
362 4
	public function draft($accountId, $subject, $body, $to, $cc, $bcc, $uid, $messageId) {
363 4
		if (is_null($uid)) {
364 2
			$this->logger->info("Saving a new draft in account <$accountId>");
365 2
		} else {
366 2
			$this->logger->info("Updating draft <$uid> in account <$accountId>");
367
		}
368
369 4
		$account = $this->accountService->find($this->currentUserId, $accountId);
370 4
		if ($account instanceof UnifiedAccount) {
371 2
			list($account) = $account->resolve($messageId);
372 2
		}
373 4
		if (!$account instanceof Account) {
374
			return new JSONResponse(
375
				array('message' => 'Invalid account'),
376
				Http::STATUS_BAD_REQUEST
377
			);
378
		}
379
380 4
		$message = $account->newMessage();
381 4
		$message->setTo(Message::parseAddressList($to));
382 4
		$message->setSubject($subject ? : '');
383 4
		$message->setFrom($account->getEMailAddress());
384 4
		$message->setCC(Message::parseAddressList($cc));
385 4
		$message->setBcc(Message::parseAddressList($bcc));
386 4
		$message->setContent($body);
387
388
		// create transport and save message
389
		try {
390 4
			$newUID = $account->saveDraft($message, $uid);
391 4
		} 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...
392
			$this->logger->error('Saving draft failed: ' . $ex->getMessage());
393
			return new JSONResponse(
394
				[
395
					'message' => $ex->getMessage()
396
				],
397
				Http::STATUS_INTERNAL_SERVER_ERROR
398
			);
399
		}
400
401 4
		return new JSONResponse([
402
			'uid' => $newUID
403 4
		]);
404
	}
405
406
}
407