diff options
author | Roeland Jago Douma <rullzer@users.noreply.github.com> | 2016-08-17 11:50:41 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-08-17 11:50:41 +0200 |
commit | c5d0a056de10622b4d5f94deef8a25e95dfb8371 (patch) | |
tree | 24139b523335b66b9c3da77c91685438b6d5132c /settings/Controller | |
parent | ce0604bd0627c62671d46d443639815ade4d4852 (diff) | |
parent | 789082e014bc7b4ecea53be088521d41407fed7b (diff) | |
download | nextcloud-server-c5d0a056de10622b4d5f94deef8a25e95dfb8371.tar.gz nextcloud-server-c5d0a056de10622b4d5f94deef8a25e95dfb8371.zip |
Merge pull request #868 from nextcloud/changepasswordcontroller
Make ChangePassword a real Controller
Diffstat (limited to 'settings/Controller')
-rw-r--r-- | settings/Controller/ChangePasswordController.php | 253 |
1 files changed, 253 insertions, 0 deletions
diff --git a/settings/Controller/ChangePasswordController.php b/settings/Controller/ChangePasswordController.php new file mode 100644 index 00000000000..74abd8b57d3 --- /dev/null +++ b/settings/Controller/ChangePasswordController.php @@ -0,0 +1,253 @@ +<?php +/** + * + * @author Roeland Jago Douma <roeland@famdouma.nl> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ +namespace OC\Settings\Controller; + +use OCP\App\IAppManager; +use OCP\AppFramework\Controller; +use OCP\AppFramework\Http\JSONResponse; +use OCP\IGroupManager; +use OCP\IL10N; +use OCP\IRequest; +use OCP\IUser; +use OCP\IUserManager; +use OCP\IUserSession; + +class ChangePasswordController extends Controller { + + /** @var string */ + private $userId; + + /** @var IUserManager */ + private $userManager; + + /** @var IL10N */ + private $l; + + /** @var IGroupManager */ + private $groupManager; + + /** @var IUserSession */ + private $userSession; + + /** @var IAppManager */ + private $appManager; + + /** + * ChangePasswordController constructor. + * + * @param string $appName + * @param IRequest $request + * @param $userId + * @param IUserManager $userManager + * @param IUserSession $userSession + * @param IGroupManager $groupManager + * @param IAppManager $appManager + * @param IL10N $l + */ + public function __construct($appName, + IRequest $request, + $userId, + IUserManager $userManager, + IUserSession $userSession, + IGroupManager $groupManager, + IAppManager $appManager, + IL10N $l) { + parent::__construct($appName, $request); + + $this->userId = $userId; + $this->userManager = $userManager; + $this->userSession = $userSession; + $this->groupManager = $groupManager; + $this->appManager = $appManager; + $this->l = $l; + } + + /** + * @NoAdminRequired + * + * @param string $oldpassword + * @param string $newpassword + * + * @return JSONResponse + */ + public function changePersonalPassword($oldpassword = '', $newpassword = null) { + $user = $this->userManager->checkPassword($this->userId, $oldpassword); + if ($user === false) { + return new JSONResponse([ + 'status' => 'error', + 'data' => [ + 'message' => $this->l->t('Wrong password'), + ], + ]); + } + + /** @var IUser $user */ + if ($newpassword === null || $user->setPassword($newpassword) === false) { + return new JSONResponse([ + 'status' => 'error' + ]); + } + + $this->userSession->updateSessionTokenPassword($newpassword); + + return new JSONResponse([ + 'status' => 'success', + 'data' => [ + 'message' => $this->l->t('Saved'), + ], + ]); + } + + /** + * @NoAdminRequired + * + * @param string $username + * @param string $password + * @param string $recoveryPassword + * + * @return JSONResponse + */ + public function changeUserPassword($username = null, $password = null, $recoveryPassword = null) { + if ($username === null) { + return new JSONResponse([ + 'status' => 'error', + 'data' => [ + 'message' => $this->l->t('No user supplied'), + ], + ]); + } + + if ($password === null) { + return new JSONResponse([ + 'status' => 'error', + 'data' => [ + 'message' => $this->l->t('Unable to change password'), + ], + ]); + } + + $currentUser = $this->userSession->getUser(); + $targetUser = $this->userManager->get($username); + if ($currentUser === null || $targetUser === null || + !($this->groupManager->isAdmin($this->userId) || + $this->groupManager->getSubAdmin()->isUserAccessible($currentUser, $targetUser)) + ) { + return new JSONResponse([ + 'status' => 'error', + 'data' => [ + 'message' => $this->l->t('Authentication error'), + ], + ]); + } + + if ($this->appManager->isEnabledForUser('encryption')) { + //handle the recovery case + $crypt = new \OCA\Encryption\Crypto\Crypt( + \OC::$server->getLogger(), + \OC::$server->getUserSession(), + \OC::$server->getConfig(), + \OC::$server->getL10N('encryption')); + $keyStorage = \OC::$server->getEncryptionKeyStorage(); + $util = new \OCA\Encryption\Util( + new \OC\Files\View(), + $crypt, + \OC::$server->getLogger(), + \OC::$server->getUserSession(), + \OC::$server->getConfig(), + \OC::$server->getUserManager()); + $keyManager = new \OCA\Encryption\KeyManager( + $keyStorage, + $crypt, + \OC::$server->getConfig(), + \OC::$server->getUserSession(), + new \OCA\Encryption\Session(\OC::$server->getSession()), + \OC::$server->getLogger(), + $util); + $recovery = new \OCA\Encryption\Recovery( + \OC::$server->getUserSession(), + $crypt, + \OC::$server->getSecureRandom(), + $keyManager, + \OC::$server->getConfig(), + $keyStorage, + \OC::$server->getEncryptionFilesHelper(), + new \OC\Files\View()); + $recoveryAdminEnabled = $recovery->isRecoveryKeyEnabled(); + + $validRecoveryPassword = false; + $recoveryEnabledForUser = false; + if ($recoveryAdminEnabled) { + $validRecoveryPassword = $keyManager->checkRecoveryPassword($recoveryPassword); + $recoveryEnabledForUser = $recovery->isRecoveryEnabledForUser($username); + } + + if ($recoveryEnabledForUser && $recoveryPassword === '') { + return new JSONResponse([ + 'status' => 'error', + 'data' => [ + 'message' => $this->l->t('Please provide an admin recovery password, otherwise all user data will be lost'), + ] + ]); + } elseif ($recoveryEnabledForUser && ! $validRecoveryPassword) { + return new JSONResponse([ + 'status' => 'error', + 'data' => [ + 'message' => $this->l->t('Wrong admin recovery password. Please check the password and try again.'), + ] + ]); + } else { // now we know that everything is fine regarding the recovery password, let's try to change the password + $result = $targetUser->setPassword($password, $recoveryPassword); + if (!$result && $recoveryEnabledForUser) { + return new JSONResponse([ + 'status' => 'error', + 'data' => [ + 'message' => $this->l->t('Backend doesn\'t support password change, but the user\'s encryption key was successfully updated.'), + ] + ]); + } elseif (!$result && !$recoveryEnabledForUser) { + return new JSONResponse([ + 'status' => 'error', + 'data' => [ + 'message' => $this->l->t('Unable to change password'), + ] + ]); + } + } + } else { + if ($targetUser->setPassword($password) === false) { + return new JSONResponse([ + 'status' => 'error', + 'data' => [ + 'message' => $this->l->t('Unable to change password'), + ], + ]); + } + } + + return new JSONResponse([ + 'status' => 'success', + 'data' => [ + 'username' => $username, + ], + ]); + } +} |