Completed
Push — master ( ca3aef...5b2d6b )
by Morris
15:49
created

ChangePasswordController::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 17
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 15
c 0
b 0
f 0
nc 1
nop 8
dl 0
loc 17
rs 9.4285

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
/**
3
 *
4
 * @author Roeland Jago Douma <[email protected]>
5
 *
6
 * @license GNU AGPL version 3 or any later version
7
 *
8
 * This program is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU Affero General Public License as
10
 * published by the Free Software Foundation, either version 3 of the
11
 * License, or (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU Affero General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Affero General Public License
19
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
 *
21
 */
22
namespace OC\Settings\Controller;
23
24
use OC\HintException;
25
use OC\User\Session;
26
use OCP\App\IAppManager;
27
use OCP\AppFramework\Controller;
28
use OCP\AppFramework\Http\JSONResponse;
29
use OCP\IGroupManager;
30
use OCP\IL10N;
31
use OCP\IRequest;
32
use OCP\IUser;
33
use OCP\IUserManager;
34
use OCP\IUserSession;
35
36
class ChangePasswordController extends Controller {
37
38
	/** @var string */
39
	private $userId;
40
41
	/** @var IUserManager */
42
	private $userManager;
43
44
	/** @var IL10N */
45
	private $l;
46
47
	/** @var IGroupManager */
48
	private $groupManager;
49
50
	/** @var Session */
51
	private $userSession;
52
53
	/** @var IAppManager */
54
	private $appManager;
55
56
	/**
57
	 * ChangePasswordController constructor.
58
	 *
59
	 * @param string $appName
60
	 * @param IRequest $request
61
	 * @param $userId
62
	 * @param IUserManager $userManager
63
	 * @param IUserSession $userSession
64
	 * @param IGroupManager $groupManager
65
	 * @param IAppManager $appManager
66
	 * @param IL10N $l
67
	 */
68
	public function __construct($appName,
69
								IRequest $request,
70
								$userId,
71
								IUserManager $userManager,
72
								IUserSession $userSession,
73
								IGroupManager $groupManager,
74
								IAppManager $appManager,
75
								IL10N $l) {
76
		parent::__construct($appName, $request);
77
78
		$this->userId = $userId;
79
		$this->userManager = $userManager;
80
		$this->userSession = $userSession;
0 ignored issues
show
Documentation Bug introduced by
$userSession is of type object<OCP\IUserSession>, but the property $userSession was declared to be of type object<OC\User\Session>. Are you sure that you always receive this specific sub-class here, or does it make sense to add an instanceof check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a given class or a super-class is assigned to a property that is type hinted more strictly.

Either this assignment is in error or an instanceof check should be added for that assignment.

class Alien {}

class Dalek extends Alien {}

class Plot
{
    /** @var  Dalek */
    public $villain;
}

$alien = new Alien();
$plot = new Plot();
if ($alien instanceof Dalek) {
    $plot->villain = $alien;
}
Loading history...
81
		$this->groupManager = $groupManager;
82
		$this->appManager = $appManager;
83
		$this->l = $l;
84
	}
85
86
	/**
87
	 * @NoAdminRequired
88
	 * @NoSubadminRequired
89
	 * @BruteForceProtection(action=changePersonalPassword)
90
	 *
91
	 * @param string $oldpassword
92
	 * @param string $newpassword
93
	 *
94
	 * @return JSONResponse
95
	 */
96
	public function changePersonalPassword($oldpassword = '', $newpassword = null) {
97
		/** @var IUser $user */
98
		$user = $this->userManager->checkPassword($this->userId, $oldpassword);
99 View Code Duplication
		if ($user === false) {
100
			$response = new JSONResponse([
101
				'status' => 'error',
102
				'data' => [
103
					'message' => $this->l->t('Wrong password'),
104
				],
105
			]);
106
			$response->throttle();
107
			return $response;
108
		}
109
110
		try {
111
			if ($newpassword === null || $user->setPassword($newpassword) === false) {
112
				return new JSONResponse([
113
					'status' => 'error'
114
				]);
115
			}
116
		// password policy app throws exception
117
		} catch(HintException $e) {
118
			return new JSONResponse([
119
				'status' => 'error',
120
				'data' => [
121
					'message' => $e->getHint(),
122
				],
123
			]);
124
		}
125
126
		$this->userSession->updateSessionTokenPassword($newpassword);
127
128
		return new JSONResponse([
129
			'status' => 'success',
130
			'data' => [
131
				'message' => $this->l->t('Saved'),
132
			],
133
		]);
134
	}
135
136
	/**
137
	 * @NoAdminRequired
138
	 * @PasswordConfirmationRequired
139
	 *
140
	 * @param string $username
141
	 * @param string $password
142
	 * @param string $recoveryPassword
143
	 *
144
	 * @return JSONResponse
145
	 */
146
	public function changeUserPassword($username = null, $password = null, $recoveryPassword = null) {
147
		if ($username === null) {
148
			return new JSONResponse([
149
				'status' => 'error',
150
				'data' => [
151
					'message' => $this->l->t('No user supplied'),
152
				],
153
			]);
154
		}
155
156
		if ($password === null) {
157
			return new JSONResponse([
158
				'status' => 'error',
159
				'data' => [
160
					'message' => $this->l->t('Unable to change password'),
161
				],
162
			]);
163
		}
164
165
		$currentUser = $this->userSession->getUser();
166
		$targetUser = $this->userManager->get($username);
167
		if ($currentUser === null || $targetUser === null ||
168
			!($this->groupManager->isAdmin($this->userId) ||
169
			 $this->groupManager->getSubAdmin()->isUserAccessible($currentUser, $targetUser))
170
		) {
171
			return new JSONResponse([
172
				'status' => 'error',
173
				'data' => [
174
					'message' => $this->l->t('Authentication error'),
175
				],
176
			]);
177
		}
178
179
		if ($this->appManager->isEnabledForUser('encryption')) {
180
			//handle the recovery case
181
			$crypt = new \OCA\Encryption\Crypto\Crypt(
182
				\OC::$server->getLogger(),
183
				\OC::$server->getUserSession(),
184
				\OC::$server->getConfig(),
185
				\OC::$server->getL10N('encryption'));
186
			$keyStorage = \OC::$server->getEncryptionKeyStorage();
187
			$util = new \OCA\Encryption\Util(
188
				new \OC\Files\View(),
189
				$crypt,
190
				\OC::$server->getLogger(),
191
				\OC::$server->getUserSession(),
192
				\OC::$server->getConfig(),
193
				\OC::$server->getUserManager());
194
			$keyManager = new \OCA\Encryption\KeyManager(
195
				$keyStorage,
196
				$crypt,
197
				\OC::$server->getConfig(),
198
				\OC::$server->getUserSession(),
199
				new \OCA\Encryption\Session(\OC::$server->getSession()),
200
				\OC::$server->getLogger(),
201
				$util);
202
			$recovery = new \OCA\Encryption\Recovery(
203
				\OC::$server->getUserSession(),
204
				$crypt,
205
				\OC::$server->getSecureRandom(),
206
				$keyManager,
207
				\OC::$server->getConfig(),
208
				$keyStorage,
209
				\OC::$server->getEncryptionFilesHelper(),
210
				new \OC\Files\View());
211
			$recoveryAdminEnabled = $recovery->isRecoveryKeyEnabled();
212
213
			$validRecoveryPassword = false;
214
			$recoveryEnabledForUser = false;
215
			if ($recoveryAdminEnabled) {
216
				$validRecoveryPassword = $keyManager->checkRecoveryPassword($recoveryPassword);
217
				$recoveryEnabledForUser = $recovery->isRecoveryEnabledForUser($username);
218
			}
219
220
			if ($recoveryEnabledForUser && $recoveryPassword === '') {
221
				return new JSONResponse([
222
					'status' => 'error',
223
					'data' => [
224
						'message' => $this->l->t('Please provide an admin recovery password; otherwise, all user data will be lost.'),
225
					]
226
				]);
227
			} elseif ($recoveryEnabledForUser && ! $validRecoveryPassword) {
228
				return new JSONResponse([
229
					'status' => 'error',
230
					'data' => [
231
						'message' => $this->l->t('Wrong admin recovery password. Please check the password and try again.'),
232
					]
233
				]);
234
			} else { // now we know that everything is fine regarding the recovery password, let's try to change the password
235
				try {
236
					$result = $targetUser->setPassword($password, $recoveryPassword);
237
				// password policy app throws exception
238
				} catch(HintException $e) {
239
					return new JSONResponse([
240
						'status' => 'error',
241
						'data' => [
242
							'message' => $e->getHint(),
243
						],
244
					]);
245
				}
246
				if (!$result && $recoveryEnabledForUser) {
247
					return new JSONResponse([
248
						'status' => 'error',
249
						'data' => [
250
							'message' => $this->l->t('Backend doesn\'t support password change, but the user\'s encryption key was updated.'),
251
						]
252
					]);
253
				} elseif (!$result && !$recoveryEnabledForUser) {
254
					return new JSONResponse([
255
						'status' => 'error',
256
						'data' => [
257
							'message' => $this->l->t('Unable to change password'),
258
						]
259
					]);
260
				}
261
			}
262
		} else {
263
			try {
264 View Code Duplication
				if ($targetUser->setPassword($password) === false) {
265
					return new JSONResponse([
266
						'status' => 'error',
267
						'data' => [
268
							'message' => $this->l->t('Unable to change password'),
269
						],
270
					]);
271
				}
272
			// password policy app throws exception
273
			} catch(HintException $e) {
274
				return new JSONResponse([
275
					'status' => 'error',
276
					'data' => [
277
						'message' => $e->getHint(),
278
					],
279
				]);
280
			}
281
		}
282
283
		return new JSONResponse([
284
			'status' => 'success',
285
			'data' => [
286
				'username' => $username,
287
			],
288
		]);
289
	}
290
}
291