diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index b487f2a6aa..b78249d51f 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -642,6 +642,7 @@ phutil_register_library_map(array( 'PhabricatorUserLog' => 'applications/people/storage/log', 'PhabricatorUserOAuthInfo' => 'applications/people/storage/useroauthinfo', 'PhabricatorUserOAuthSettingsPanelController' => 'applications/people/controller/settings/panels/oauth', + 'PhabricatorUserPasswordSettingsPanelController' => 'applications/people/controller/settings/panels/password', 'PhabricatorUserPreferenceSettingsPanelController' => 'applications/people/controller/settings/panels/preferences', 'PhabricatorUserPreferences' => 'applications/people/storage/preferences', 'PhabricatorUserProfile' => 'applications/people/storage/profile', @@ -1222,6 +1223,7 @@ phutil_register_library_map(array( 'PhabricatorUserLog' => 'PhabricatorUserDAO', 'PhabricatorUserOAuthInfo' => 'PhabricatorUserDAO', 'PhabricatorUserOAuthSettingsPanelController' => 'PhabricatorUserSettingsPanelController', + 'PhabricatorUserPasswordSettingsPanelController' => 'PhabricatorUserSettingsPanelController', 'PhabricatorUserPreferenceSettingsPanelController' => 'PhabricatorUserSettingsPanelController', 'PhabricatorUserPreferences' => 'PhabricatorUserDAO', 'PhabricatorUserProfile' => 'PhabricatorUserDAO', diff --git a/src/applications/people/controller/settings/PhabricatorUserSettingsController.php b/src/applications/people/controller/settings/PhabricatorUserSettingsController.php index acc107b519..120e2d3f2e 100644 --- a/src/applications/people/controller/settings/PhabricatorUserSettingsController.php +++ b/src/applications/people/controller/settings/PhabricatorUserSettingsController.php @@ -29,16 +29,20 @@ class PhabricatorUserSettingsController extends PhabricatorPeopleController { $request = $this->getRequest(); - // TODO: Implement a password panel. - $this->pages = array( 'account' => 'Account', 'profile' => 'Profile', 'email' => 'Email', + 'password' => 'Password', 'preferences' => 'Preferences', 'conduit' => 'Conduit Certificate', ); + if (!PhabricatorEnv::getEnvConfig('account.editable') || + !PhabricatorEnv::getEnvConfig('auth.password-auth-enabled')) { + unset($this->pages['password']); + } + if (PhabricatorUserSSHKeysSettingsPanelController::isEnabled()) { $this->pages['sshkeys'] = 'SSH Public Keys'; } @@ -67,6 +71,10 @@ class PhabricatorUserSettingsController extends PhabricatorPeopleController { case 'email': $delegate = new PhabricatorUserEmailSettingsPanelController($request); break; + case 'password': + $delegate = new PhabricatorUserPasswordSettingsPanelController( + $request); + break; case 'conduit': $delegate = new PhabricatorUserConduitSettingsPanelController($request); break; diff --git a/src/applications/people/controller/settings/__init__.php b/src/applications/people/controller/settings/__init__.php index ec95b76f5a..08c21ebe1e 100644 --- a/src/applications/people/controller/settings/__init__.php +++ b/src/applications/people/controller/settings/__init__.php @@ -13,9 +13,11 @@ phutil_require_module('phabricator', 'applications/people/controller/settings/pa phutil_require_module('phabricator', 'applications/people/controller/settings/panels/conduit'); phutil_require_module('phabricator', 'applications/people/controller/settings/panels/email'); phutil_require_module('phabricator', 'applications/people/controller/settings/panels/oauth'); +phutil_require_module('phabricator', 'applications/people/controller/settings/panels/password'); phutil_require_module('phabricator', 'applications/people/controller/settings/panels/preferences'); phutil_require_module('phabricator', 'applications/people/controller/settings/panels/profile'); phutil_require_module('phabricator', 'applications/people/controller/settings/panels/sshkeys'); +phutil_require_module('phabricator', 'infrastructure/env'); phutil_require_module('phabricator', 'view/layout/sidenav'); phutil_require_module('phutil', 'markup'); diff --git a/src/applications/people/controller/settings/panels/password/PhabricatorUserPasswordSettingsPanelController.php b/src/applications/people/controller/settings/panels/password/PhabricatorUserPasswordSettingsPanelController.php new file mode 100644 index 0000000000..06dae9d2ff --- /dev/null +++ b/src/applications/people/controller/settings/panels/password/PhabricatorUserPasswordSettingsPanelController.php @@ -0,0 +1,111 @@ +getRequest(); + $user = $request->getUser(); + $editable = $this->getAccountEditable(); + + // There's no sense in showing a change password panel if the user + // can't change their password + if (!$editable || + !PhabricatorEnv::getEnvConfig('auth.password-auth-enabled')) { + return new Aphront400Response(); + } + + $errors = array(); + if ($request->isFormPost()) { + if ($user->comparePassword($request->getStr('old_pw'))) { + $pass = $request->getStr('new_pw'); + $conf = $request->getStr('conf_pw'); + if ($pass === $conf) { + if (strlen($pass)) { + $user->setPassword($pass); + // This write is unguarded because the CSRF token has already + // been checked in the call to $request->isFormPost() and + // the CSRF token depends on the password hash, so when it + // is changed here the CSRF token check will fail. + $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites(); + $user->save(); + unset($unguarded); + return id(new AphrontRedirectResponse()) + ->setURI('/settings/page/password/?saved=true'); + } else { + $errors[] = 'Your new password is too short.'; + } + } else { + $errors[] = 'New password and confirmation do not match.'; + } + } else { + $errors[] = 'The old password you entered is incorrect.'; + } + } + + $notice = null; + if (!$errors) { + if ($request->getStr('saved')) { + $notice = new AphrontErrorView(); + $notice->setSeverity(AphrontErrorView::SEVERITY_NOTICE); + $notice->setTitle('Changes Saved'); + $notice->appendChild('
Your password has been updated.
'); + } + } else { + $notice = new AphrontErrorView(); + $notice->setTitle('Error Changing Password'); + $notice->setErrors($errors); + } + + $form = new AphrontFormView(); + $form + ->setUser($user) + ->appendChild( + id(new AphrontFormPasswordControl()) + ->setLabel('Old Password') + ->setName('old_pw')); + $form + ->appendChild( + id(new AphrontFormPasswordControl()) + ->setLabel('New Password') + ->setName('new_pw')); + $form + ->appendChild( + id(new AphrontFormPasswordControl()) + ->setLabel('Confirm Password') + ->setName('conf_pw')); + $form + ->appendChild( + id(new AphrontFormSubmitControl()) + ->setValue('Save')); + + $panel = new AphrontPanelView(); + $panel->setHeader('Change Password'); + $panel->setWidth(AphrontPanelView::WIDTH_FORM); + $panel->appendChild($form); + + return id(new AphrontNullView()) + ->appendChild( + array( + $notice, + $panel, + )); + } +} diff --git a/src/applications/people/controller/settings/panels/password/__init__.php b/src/applications/people/controller/settings/panels/password/__init__.php new file mode 100644 index 0000000000..7a375a6fd8 --- /dev/null +++ b/src/applications/people/controller/settings/panels/password/__init__.php @@ -0,0 +1,24 @@ +