Completed
Pull Request — master (#32767)
by Sujith
69:57 queued 39:50
created

UserSendMail::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 13

Duplication

Lines 13
Ratio 100 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 7
dl 13
loc 13
rs 9.8333
c 0
b 0
f 0
1
<?php
2
/**
3
 * @author Sujith Haridasan <[email protected]>
4
 *
5
 * @copyright Copyright (c) 2018, ownCloud GmbH
6
 * @license AGPL-3.0
7
 *
8
 * This code is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU Affero General Public License, version 3,
10
 * as published by the Free Software Foundation.
11
 *
12
 * This program is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
 * GNU Affero General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Affero General Public License, version 3,
18
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
19
 *
20
 */
21
22
namespace OC\User\Service;
23
24
use OCP\AppFramework\Http\TemplateResponse;
25
use OCP\AppFramework\Utility\ITimeFactory;
26
use OCP\IConfig;
27
use OCP\IL10N;
28
use OCP\IURLGenerator;
29
use OCP\IUser;
30
use OCP\Mail\IMailer;
31
use OCP\Security\ISecureRandom;
32
use OCP\User\Exceptions\InvalidUserTokenException;
33
use OCP\User\Exceptions\UserTokenExpiredException;
34
use OCP\User\Exceptions\UserTokenMismatchException;
35
use OCP\Util;
36
37
class UserSendMail {
38
	/** @var ISecureRandom  */
39
	private $secureRandom;
40
	/** @var IConfig  */
41
	private $config;
42
	/** @var IMailer  */
43
	private $mailer;
44
	/** @var IURLGenerator  */
45
	private $urlGenerator;
46
	/** @var \OC_Defaults  */
47
	private $defaults;
48
	/** @var ITimeFactory  */
49
	private $timeFactory;
50
	/** @var string  */
51
	private $fromMailAddress;
52
	/** @var IL10N  */
53
	private $l10n;
54
55
	/**
56
	 * UserSendMail constructor.
57
	 *
58
	 * @param ISecureRandom $secureRandom
59
	 * @param IConfig $config
60
	 * @param IMailer $mailer
61
	 * @param IURLGenerator $urlGenerator
62
	 * @param \OC_Defaults $defaults
63
	 * @param ITimeFactory $timeFactory
64
	 * @param IL10N $l10n
65
	 */
66 View Code Duplication
	public function __construct(ISecureRandom $secureRandom, IConfig $config,
67
								IMailer $mailer, IURLGenerator $urlGenerator,
68
								\OC_Defaults $defaults, ITimeFactory $timeFactory,
69
								IL10N $l10n) {
70
		$this->secureRandom = $secureRandom;
71
		$this->config = $config;
72
		$this->mailer = $mailer;
73
		$this->urlGenerator = $urlGenerator;
74
		$this->defaults = $defaults;
75
		$this->timeFactory = $timeFactory;
76
		$this->l10n = $l10n;
77
		$this->fromMailAddress = Util::getDefaultEmailAddress('no-reply');
78
	}
79
80
	/**
81
	 * @param string $userId
82
	 * @param string $email
83
	 * @return null
84
	 */
85
	public function generateTokenAndSendMail($userId, $email) {
86
		$token = $this->secureRandom->generate(21,
87
			ISecureRandom::CHAR_DIGITS,
88
			ISecureRandom::CHAR_LOWER, ISecureRandom::CHAR_UPPER);
0 ignored issues
show
Unused Code introduced by
The call to ISecureRandom::generate() has too many arguments starting with \OCP\Security\ISecureRandom::CHAR_LOWER.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
89
		$this->config->setUserValue($userId, 'owncloud',
90
			'lostpassword', $this->timeFactory->getTime() . ':' . $token);
91
92
		// data for the mail template
93
		$mailData = [
94
			'username' => $userId,
95
			'url' => $this->urlGenerator->linkToRouteAbsolute('core.user.setPasswordForm', ['userId' => $userId, 'token' => $token])
96
		];
97
98
		$mail = new TemplateResponse('core', 'new_user/email-html', $mailData, 'blank');
99
		$mailContent = $mail->render();
100
101
		$mail = new TemplateResponse('core', 'new_user/email-plain_text', $mailData, 'blank');
102
		$plainTextMailContent = $mail->render();
103
104
		$subject = $this->l10n->t('Your %s account was created', [$this->defaults->getName()]);
105
106
		$message = $this->mailer->createMessage();
107
		$message->setTo([$email => $userId]);
108
		$message->setSubject($subject);
109
		$message->setHtmlBody($mailContent);
0 ignored issues
show
Bug introduced by
It seems like $mailContent defined by $mail->render() on line 99 can also be of type boolean; however, OC\Mail\Message::setHtmlBody() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
110
		$message->setPlainBody($plainTextMailContent);
0 ignored issues
show
Bug introduced by
It seems like $plainTextMailContent defined by $mail->render() on line 102 can also be of type boolean; however, OC\Mail\Message::setPlainBody() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
111
		$message->setFrom([$this->fromMailAddress => $this->defaults->getName()]);
112
		$this->mailer->send($message);
113
	}
114
115
	/**
116
	 * @param string $token
117
	 * @param IUser $user
118
	 * @return null
119
	 * @throws InvalidUserTokenException
120
	 * @throws UserTokenExpiredException
121
	 * @throws UserTokenMismatchException
122
	 */
123
	public function checkPasswordSetToken($token, IUser $user) {
124
125
		$splittedToken = \explode(':', $this->config->getUserValue($user->getUID(), 'owncloud', 'lostpassword', null));
126
		if (\count($splittedToken) !== 2) {
127
			$this->config->deleteUserValue($user->getUID(), 'owncloud', 'lostpassword');
128
			throw new InvalidUserTokenException($this->l10n->t('The token provided is invalid.'));
129
		}
130
131
		//The value 43200 = 60*60*12 = 1/2 day
132
		if ($splittedToken[0] < ($this->timeFactory->getTime() - (int)$this->config->getAppValue('core', 'token_expire_time', '43200')) ||
133
			$user->getLastLogin() > $splittedToken[0]) {
134
			$this->config->deleteUserValue($user->getUID(), 'owncloud', 'lostpassword');
135
			throw new UserTokenExpiredException($this->l10n->t('The token provided had expired.'));
136
		}
137
138
		if (!\hash_equals($splittedToken[1], $token)) {
139
			throw new UserTokenMismatchException($this->l10n->t('The token provided is invalid.'));
140
		}
141
	}
142
143
	/**
144
	 * @param IUser $user
145
	 * @return null
146
	 * @throws \Exception
147
	 */
148
	public function sendNotificationMail($user) {
149
		$email = $user->getEMailAddress();
150
151
		if ($email !== '') {
152
			$tmpl = new \OC_Template('core', 'lostpassword/notify');
153
			$msg = $tmpl->fetchPage();
154
155
			$message = $this->mailer->createMessage();
156
			$message->setTo([$email => $user->getUID()]);
157
			$message->setSubject($this->l10n->t('%s password changed successfully', [$this->defaults->getName()]));
158
			$message->setPlainBody($msg);
0 ignored issues
show
Bug introduced by
It seems like $msg defined by $tmpl->fetchPage() on line 153 can also be of type boolean; however, OC\Mail\Message::setPlainBody() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
159
			$message->setFrom([$email => $this->defaults->getName()]);
160
			$this->mailer->send($message);
161
		}
162
	}
163
}