Completed
Pull Request — master (#32767)
by Sujith
17:56 queued 07:59
created

UserController::setPassword()   B

Complexity

Conditions 5
Paths 11

Size

Total Lines 57

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
nc 11
nop 3
dl 0
loc 57
rs 8.627
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
 * @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\EmailSendFailedException;
37
use OCP\User\Exceptions\UserTokenException;
38
use OCP\User\Exceptions\UserTokenExpiredException;
39
40
class UserController extends Controller {
41
	/**
42
	 * @var \OCP\IUserManager
43
	 */
44
	protected $userManager;
45
46
	/**
47
	 * @var \OC_Defaults
48
	 */
49
	protected $defaults;
50
	private $userSendMail;
51
	private $urlGenerator;
52
	private $log;
53
	private $l10n;
54
55
	public function __construct($appName,
56
								IRequest $request,
57
								$userManager,
58
								$defaults,
59
								UserSendMail $userSendMail,
60
								IURLGenerator $urlGenerator,
61
								ILogger $log,
62
								IL10N $l10n
63
	) {
64
		parent::__construct($appName, $request);
65
		$this->userManager = $userManager;
66
		$this->defaults = $defaults;
67
		$this->userSendMail = $userSendMail;
68
		$this->urlGenerator = $urlGenerator;
69
		$this->log = $log;
70
		$this->l10n = $l10n;
71
	}
72
73
	/**
74
	 * Lookup user display names
75
	 *
76
	 * @NoAdminRequired
77
	 *
78
	 * @param array $users
79
	 *
80
	 * @return JSONResponse
81
	 */
82
	public function getDisplayNames($users) {
83
		$result = [];
84
85
		foreach ($users as $user) {
86
			$userObject = $this->userManager->get($user);
87
			if (\is_object($userObject)) {
88
				$result[$user] = $userObject->getDisplayName();
89
			} else {
90
				$result[$user] = $user;
91
			}
92
		}
93
94
		$json = [
95
			'users' => $result,
96
			'status' => 'success'
97
		];
98
99
		return new JSONResponse($json);
100
	}
101
102
	/**
103
	 * Set password for user using link
104
	 *
105
	 * @PublicPage
106
	 * @NoCSRFRequired
107
	 * @NoAdminRequired
108
	 * @NoSubadminRequired
109
	 *
110
	 * @param string $token
111
	 * @param string $userId
112
	 * @return TemplateResponse
113
	 */
114
	public function setPasswordForm($token, $userId) {
115
		try {
116
			$user = $this->userManager->get($userId);
117
			$this->userSendMail->checkPasswordSetToken($token, $user);
0 ignored issues
show
Bug introduced by
It seems like $user defined by $this->userManager->get($userId) on line 116 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...
118
		} catch (UserTokenException $e) {
119
			if ($e instanceof UserTokenExpiredException) {
120
				return new TemplateResponse(
121
					'core', 'new_user/resendtokenbymail',
122
					[
123
						'link' => $this->urlGenerator->linkToRouteAbsolute('core.user.resendToken', ['userId' => $userId])
124
					], 'guest'
125
				);
126
			}
127
			$this->log->logException($e, ['app' => 'core']);
128
			return new TemplateResponse(
129
				'core', 'error',
130
				[
131
					"errors" => [["error" => $this->l10n->t($e->getMessage())]]
132
				], 'guest'
133
			);
134
		}
135
136
		return new TemplateResponse(
137
			'core', 'new_user/setpassword',
138
			[
139
				'link' => $this->urlGenerator->linkToRouteAbsolute('core.user.setPassword', ['userId' => $userId, 'token' => $token])
140
			], 'guest'
141
		);
142
	}
143
144
	/**
145
	 * @PublicPage
146
	 * @NoCSRFRequired
147
	 * @NoAdminRequired
148
	 * @NoSubadminRequired
149
	 *
150
	 * @param string $userId
151
	 * @return TemplateResponse
152
	 */
153
	public function resendToken($userId) {
154
		$user = $this->userManager->get($userId);
155
156 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...
157
			$this->log->error('User: ' . $userId . ' does not exist', ['app' => 'core']);
158
			return new TemplateResponse(
159
				'core', 'error',
160
				[
161
					"errors" => [["error" => $this->l10n->t('Failed to create activation link. Please contact your administrator.')]]
162
				],
163
				'guest'
164
			);
165
		}
166
167 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...
168
			$this->log->error('Email address not set for: ' . $userId, ['app' => 'core']);
169
			return new TemplateResponse(
170
				'core', 'error',
171
				[
172
					"errors" => [["error" => $this->l10n->t('Failed to create activation link. Please contact your administrator.', [$userId])]]
173
				],
174
				'guest'
175
			);
176
		}
177
178
		try {
179
			$this->userSendMail->generateTokenAndSendMail($user->getUID(), $user->getEMailAddress());
180
		} catch (\Exception $e) {
181
			$this->log->error("Can't send new user mail to " . $user->getEMailAddress() . ": " . $e->getMessage(), ['app' => 'core']);
182
			return new TemplateResponse(
183
				'core', 'error',
184
				[
185
					"errors" => [[
186
						"error" => $this->l10n->t('Can\'t send email to the user. Contact your administrator.')]]
187
				], 'guest'
188
			);
189
		}
190
191
		return new TemplateResponse(
192
			'core', 'new_user/tokensendnotify', [], 'guest'
193
		);
194
	}
195
196
	/**
197
	 * @PublicPage
198
	 * @NoAdminRequired
199
	 * @NoSubadminRequired
200
	 * @NoCSRFRequired
201
	 *
202
	 * @param string $token
203
	 * @param string $userId
204
	 * @param string $password
205
	 * @return JSONResponse
206
	 */
207
	public function setPassword($token, $userId, $password) {
208
		$user = $this->userManager->get($userId);
209
210
		if ($user === null) {
211
			$this->log->error('User: ' . $userId . ' does not exist.', ['app' => 'core']);
212
			return new JSONResponse(
213
				[
214
					'status' => 'error',
215
					'message' => $this->l10n->t('Failed to set password. Please contact the administrator.', [$userId]),
216
					'type' => 'usererror'
217
				], Http::STATUS_NOT_FOUND
218
			);
219
		}
220
221
		try {
222
			$this->userSendMail->checkPasswordSetToken($token, $user);
223
224
			if (!$user->setPassword($password)) {
225
				$this->log->error('The password can not be set for user: '. $userId);
226
				return new JSONResponse(
227
					[
228
						'status' => 'error',
229
						'message' => $this->l10n->t('Failed to set password. Please contact your administrator.', [$userId]),
230
						'type' => 'passwordsetfailed'
231
					], Http::STATUS_FORBIDDEN
232
				);
233
			}
234
235
			\OC_Hook::emit('\OC\Core\LostPassword\Controller\LostController', 'post_passwordReset', ['uid' => $userId, 'password' => $password]);
236
			\OC_User::unsetMagicInCookie();
237
		} catch (UserTokenException $e) {
238
			$this->log->logException($e, ['app' => 'core']);
239
			return new JSONResponse(
240
				[
241
					'status' => 'error',
242
					'message' => $e->getMessage(),
243
					'type' => 'tokenfailure'
244
				], Http::STATUS_UNAUTHORIZED
245
			);
246
		}
247
248
		try {
249
			$this->userManager->get($userId);
250
			$this->userSendMail->sendNotificationMail($user);
251
		} catch (EmailSendFailedException $e) {
252
			$this->log->logException($e, ['app' => 'user_management']);
253
			return new JSONResponse(
254
				[
255
					'status' => 'error',
256
					'message' => $this->l10n->t('Failed to send email. Please contact your administrator.'),
257
					'type' => 'emailsendfailed'
258
				], Http::STATUS_INTERNAL_SERVER_ERROR
259
			);
260
		}
261
262
		return new JSONResponse(['status' => 'success']);
263
	}
264
}
265