Completed
Pull Request — master (#32767)
by Sujith
74:52 queued 26:28
created

UserController::resendToken()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 42

Duplication

Lines 20
Ratio 47.62 %

Importance

Changes 0
Metric Value
cc 4
nc 4
nop 1
dl 20
loc 42
rs 9.248
c 0
b 0
f 0
1
<?php
2
/**
3
 * @author Lukas Reschke <[email protected]>
4
 * @author Morris Jobke <[email protected]>
5
 * @author Thomas Müller <[email protected]>
6
 * @author Sujith Haridasan <[email protected]>
7
 *
8
 * @copyright Copyright (c) 2018, ownCloud GmbH
9
 * @license AGPL-3.0
10
 *
11
 * This code is free software: you can redistribute it and/or modify
12
 * it under the terms of the GNU Affero General Public License, version 3,
13
 * as published by the Free Software Foundation.
14
 *
15
 * This program is distributed in the hope that it will be useful,
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
 * GNU Affero General Public License for more details.
19
 *
20
 * You should have received a copy of the GNU Affero General Public License, version 3,
21
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
22
 *
23
 */
24
25
namespace OC\Core\Controller;
26
27
use OC\AppFramework\Http;
28
use OC\User\Service\UserSendMail;
29
use \OCP\AppFramework\Controller;
30
use \OCP\AppFramework\Http\JSONResponse;
31
use OCP\AppFramework\Http\TemplateResponse;
32
use OCP\IL10N;
33
use OCP\ILogger;
34
use \OCP\IRequest;
35
use OCP\IURLGenerator;
36
use OCP\User\Exceptions\UserTokenException;
37
use OCP\User\Exceptions\UserTokenExpiredException;
38
39
class UserController extends Controller {
40
	/**
41
	 * @var \OCP\IUserManager
42
	 */
43
	protected $userManager;
44
45
	/**
46
	 * @var \OC_Defaults
47
	 */
48
	protected $defaults;
49
	private $userSendMail;
50
	private $urlGenerator;
51
	private $log;
52
	private $l10n;
53
54
	public function __construct($appName,
55
								IRequest $request,
56
								$userManager,
57
								$defaults,
58
								UserSendMail $userSendMail,
59
								IURLGenerator $urlGenerator,
60
								ILogger $log,
61
								IL10N $l10n
62
	) {
63
		parent::__construct($appName, $request);
64
		$this->userManager = $userManager;
65
		$this->defaults = $defaults;
66
		$this->userSendMail = $userSendMail;
67
		$this->urlGenerator = $urlGenerator;
68
		$this->log = $log;
69
		$this->l10n = $l10n;
70
	}
71
72
	/**
73
	 * Lookup user display names
74
	 *
75
	 * @NoAdminRequired
76
	 *
77
	 * @param array $users
78
	 *
79
	 * @return JSONResponse
80
	 */
81
	public function getDisplayNames($users) {
82
		$result = [];
83
84
		foreach ($users as $user) {
85
			$userObject = $this->userManager->get($user);
86
			if (\is_object($userObject)) {
87
				$result[$user] = $userObject->getDisplayName();
88
			} else {
89
				$result[$user] = $user;
90
			}
91
		}
92
93
		$json = [
94
			'users' => $result,
95
			'status' => 'success'
96
		];
97
98
		return new JSONResponse($json);
99
	}
100
101
	/**
102
	 * Set password for user using link
103
	 *
104
	 * @PublicPage
105
	 * @NoCSRFRequired
106
	 * @NoAdminRequired
107
	 * @NoSubadminRequired
108
	 *
109
	 * @param string $token
110
	 * @param string $userId
111
	 * @return TemplateResponse
112
	 */
113
	public function setPasswordForm($token, $userId) {
114
		try {
115
			$user = $this->userManager->get($userId);
116
			$this->userSendMail->checkPasswordSetToken($token, $user);
0 ignored issues
show
Bug introduced by
It seems like $user defined by $this->userManager->get($userId) on line 115 can be null; however, OC\User\Service\UserSend...checkPasswordSetToken() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
117
		} catch (UserTokenException $e) {
118
			if ($e instanceof UserTokenExpiredException) {
119
				return new TemplateResponse(
120
					'core', 'new_user/resendtokenbymail',
121
					[
122
						'link' => $this->urlGenerator->linkToRouteAbsolute('core.user.resendToken', ['userId' => $userId])
123
					], 'guest'
124
				);
125
			}
126
			$this->log->logException($e, ['app' => 'core']);
127
			return new TemplateResponse(
128
				'core', 'error',
129
				[
130
					"errors" => [["error" => $e->getMessage()]]
131
				], 'guest'
132
			);
133
		}
134
135
		return new TemplateResponse(
136
			'core', 'new_user/setpassword',
137
			[
138
				'link' => $this->urlGenerator->linkToRouteAbsolute('core.user.setPassword', ['userId' => $userId, 'token' => $token])
139
			], 'guest'
140
		);
141
	}
142
143
	/**
144
	 * @PublicPage
145
	 * @NoCSRFRequired
146
	 * @NoAdminRequired
147
	 * @NoSubadminRequired
148
	 *
149
	 * @param string $userId
150
	 * @return TemplateResponse
151
	 */
152
	public function resendToken($userId) {
153
		$user = $this->userManager->get($userId);
154
155 View Code Duplication
		if ($user === null) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
156
			$this->log->error('User: ' . $userId . ' does not exist', ['app' => 'core']);
157
			return new TemplateResponse(
158
				'core', 'error',
159
				[
160
					"errors" => [["error" => $this->l10n->t('Failed to create activation link. Please contact your administrator.')]]
161
				],
162
				'guest'
163
			);
164
		}
165
166 View Code Duplication
		if ($user->getEMailAddress() === null) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
167
			$this->log->error('Email address not set for: ' . $userId, ['app' => 'core']);
168
			return new TemplateResponse(
169
				'core', 'error',
170
				[
171
					"errors" => [["error" => $this->l10n->t('Failed to create activation link. Please contact your administrator.', [$userId])]]
172
				],
173
				'guest'
174
			);
175
		}
176
177
		try {
178
			$this->userSendMail->generateTokenAndSendMail($user->getUID(), $user->getEMailAddress());
179
		} catch (\Exception $e) {
180
			$this->log->error("Can't send new user mail to " . $user->getEMailAddress() . ": " . $e->getMessage(), ['app' => 'core']);
181
			return new TemplateResponse(
182
				'core', 'error',
183
				[
184
					"errors" => [[
185
						"error" => $this->l10n->t('Can\'t send email to the user. Contact your administrator.')]]
186
				], 'guest'
187
			);
188
		}
189
190
		return new TemplateResponse(
191
			'core', 'new_user/tokensendnotify', [], 'guest'
192
		);
193
	}
194
195
	/**
196
	 * @PublicPage
197
	 * @NoAdminRequired
198
	 * @NoSubadminRequired
199
	 * @NoCSRFRequired
200
	 *
201
	 * @param string $token
202
	 * @param string $userId
203
	 * @param string $password
204
	 * @return JSONResponse
205
	 */
206
	public function setPassword($token, $userId, $password) {
207
		$user = $this->userManager->get($userId);
208
209
		if ($user === null) {
210
			$this->log->error('User: ' . $userId . ' does not exist.', ['app' => 'core']);
211
			return new JSONResponse(
212
				[
213
					'status' => 'error',
214
					'message' => $this->l10n->t('Failed to set password. Please contact the administrator.', [$userId]),
215
					'type' => 'usererror'
216
				], Http::STATUS_NOT_FOUND
217
			);
218
		}
219
220
		try {
221
			$this->userSendMail->checkPasswordSetToken($token, $user);
222
223
			if (!$user->setPassword($password)) {
224
				$this->log->error('The password can not be set for user: '. $userId);
225
				return new JSONResponse(
226
					[
227
						'status' => 'error',
228
						'message' => $this->l10n->t('Failed to set password. Please contact your administrator.', [$userId]),
229
						'type' => 'passwordsetfailed'
230
					], Http::STATUS_FORBIDDEN
231
				);
232
			}
233
234
			\OC_Hook::emit('\OC\Core\LostPassword\Controller\LostController', 'post_passwordReset', ['uid' => $userId, 'password' => $password]);
235
			\OC_User::unsetMagicInCookie();
236
		} catch (UserTokenException $e) {
237
			$this->log->logException($e, ['app' => 'core']);
238
			return new JSONResponse(
239
				[
240
					'status' => 'error',
241
					'message' => $e->getMessage(),
242
					'type' => 'tokenfailure'
243
				], Http::STATUS_UNAUTHORIZED
244
			);
245
		}
246
247
		try {
248
			$this->userManager->get($userId);
249
			$this->userSendMail->sendNotificationMail($user);
250
		} catch (\Exception $e) {
251
			$this->log->logException($e, ['app' => 'user_management']);
252
			return new JSONResponse(
253
				[
254
					'status' => 'error',
255
					'message' => $this->l10n->t('Failed to send email. Please contact your administrator.'),
256
					'type' => 'emailsendfailed'
257
				], Http::STATUS_INTERNAL_SERVER_ERROR
258
			);
259
		}
260
261
		return new JSONResponse(['status' => 'success']);
262
	}
263
}
264