1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-12-04 20:52:43 +01:00
phorge-phorge/src/applications/settings/panel/PhabricatorPasswordSettingsPanel.php
epriestley d6d93dd658 Add icons to Settings
Summary: Depends on D20005. I love icons.

Test Plan: {F6145996}

Reviewers: amckinley

Reviewed By: amckinley

Differential Revision: https://secure.phabricator.com/D20006
2019-01-23 13:41:41 -08:00

222 lines
6.9 KiB
PHP

<?php
final class PhabricatorPasswordSettingsPanel extends PhabricatorSettingsPanel {
public function getPanelKey() {
return 'password';
}
public function getPanelName() {
return pht('Password');
}
public function getPanelMenuIcon() {
return 'fa-key';
}
public function getPanelGroupKey() {
return PhabricatorSettingsAuthenticationPanelGroup::PANELGROUPKEY;
}
public function isEnabled() {
// There's no sense in showing a change password panel if this install
// doesn't support password authentication.
if (!PhabricatorPasswordAuthProvider::getPasswordProvider()) {
return false;
}
return true;
}
public function processRequest(AphrontRequest $request) {
$viewer = $request->getUser();
$user = $this->getUser();
$content_source = PhabricatorContentSource::newFromRequest($request);
$token = id(new PhabricatorAuthSessionEngine())->requireHighSecuritySession(
$viewer,
$request,
'/settings/');
$min_len = PhabricatorEnv::getEnvConfig('account.minimum-password-length');
$min_len = (int)$min_len;
// NOTE: Users can also change passwords through the separate "set/reset"
// interface which is reached by logging in with a one-time token after
// registration or password reset. If this flow changes, that flow may
// also need to change.
$account_type = PhabricatorAuthPassword::PASSWORD_TYPE_ACCOUNT;
$password_objects = id(new PhabricatorAuthPasswordQuery())
->setViewer($viewer)
->withObjectPHIDs(array($user->getPHID()))
->withPasswordTypes(array($account_type))
->withIsRevoked(false)
->execute();
if ($password_objects) {
$password_object = head($password_objects);
} else {
$password_object = PhabricatorAuthPassword::initializeNewPassword(
$user,
$account_type);
}
$e_old = true;
$e_new = true;
$e_conf = true;
$errors = array();
if ($request->isFormPost()) {
// Rate limit guesses about the old password. This page requires MFA and
// session compromise already, so this is mostly just to stop researchers
// from reporting this as a vulnerability.
PhabricatorSystemActionEngine::willTakeAction(
array($viewer->getPHID()),
new PhabricatorAuthChangePasswordAction(),
1);
$envelope = new PhutilOpaqueEnvelope($request->getStr('old_pw'));
$engine = id(new PhabricatorAuthPasswordEngine())
->setViewer($viewer)
->setContentSource($content_source)
->setPasswordType($account_type)
->setObject($user);
if (!strlen($envelope->openEnvelope())) {
$errors[] = pht('You must enter your current password.');
$e_old = pht('Required');
} else if (!$engine->isValidPassword($envelope)) {
$errors[] = pht('The old password you entered is incorrect.');
$e_old = pht('Invalid');
} else {
$e_old = null;
// Refund the user an action credit for getting the password right.
PhabricatorSystemActionEngine::willTakeAction(
array($viewer->getPHID()),
new PhabricatorAuthChangePasswordAction(),
-1);
}
$pass = $request->getStr('new_pw');
$conf = $request->getStr('conf_pw');
$password_envelope = new PhutilOpaqueEnvelope($pass);
$confirm_envelope = new PhutilOpaqueEnvelope($conf);
try {
$engine->checkNewPassword($password_envelope, $confirm_envelope);
$e_new = null;
$e_conf = null;
} catch (PhabricatorAuthPasswordException $ex) {
$errors[] = $ex->getMessage();
$e_new = $ex->getPasswordError();
$e_conf = $ex->getConfirmError();
}
if (!$errors) {
$password_object
->setPassword($password_envelope, $user)
->save();
$next = $this->getPanelURI('?saved=true');
id(new PhabricatorAuthSessionEngine())->terminateLoginSessions(
$user,
new PhutilOpaqueEnvelope(
$request->getCookie(PhabricatorCookies::COOKIE_SESSION)));
return id(new AphrontRedirectResponse())->setURI($next);
}
}
if ($password_object->getID()) {
try {
$can_upgrade = $password_object->canUpgrade();
} catch (PhabricatorPasswordHasherUnavailableException $ex) {
$can_upgrade = false;
$errors[] = pht(
'Your password is currently hashed using an algorithm which is '.
'no longer available on this install.');
$errors[] = pht(
'Because the algorithm implementation is missing, your password '.
'can not be used or updated.');
$errors[] = pht(
'To set a new password, request a password reset link from the '.
'login screen and then follow the instructions.');
}
if ($can_upgrade) {
$errors[] = pht(
'The strength of your stored password hash can be upgraded. '.
'To upgrade, either: log out and log in using your password; or '.
'change your password.');
}
}
$len_caption = null;
if ($min_len) {
$len_caption = pht('Minimum password length: %d characters.', $min_len);
}
$form = id(new AphrontFormView())
->setViewer($viewer)
->appendChild(
id(new AphrontFormPasswordControl())
->setLabel(pht('Old Password'))
->setError($e_old)
->setName('old_pw'))
->appendChild(
id(new AphrontFormPasswordControl())
->setDisableAutocomplete(true)
->setLabel(pht('New Password'))
->setError($e_new)
->setName('new_pw'))
->appendChild(
id(new AphrontFormPasswordControl())
->setDisableAutocomplete(true)
->setLabel(pht('Confirm Password'))
->setCaption($len_caption)
->setError($e_conf)
->setName('conf_pw'))
->appendChild(
id(new AphrontFormSubmitControl())
->setValue(pht('Change Password')));
$properties = id(new PHUIPropertyListView());
$properties->addProperty(
pht('Current Algorithm'),
PhabricatorPasswordHasher::getCurrentAlgorithmName(
$password_object->newPasswordEnvelope()));
$properties->addProperty(
pht('Best Available Algorithm'),
PhabricatorPasswordHasher::getBestAlgorithmName());
$info_view = id(new PHUIInfoView())
->setSeverity(PHUIInfoView::SEVERITY_NOTICE)
->appendChild(
pht('Changing your password will terminate any other outstanding '.
'login sessions.'));
$algo_box = $this->newBox(pht('Password Algorithms'), $properties);
$form_box = id(new PHUIObjectBoxView())
->setHeaderText(pht('Change Password'))
->setFormSaved($request->getStr('saved'))
->setFormErrors($errors)
->setBackground(PHUIObjectBoxView::WHITE_CONFIG)
->setForm($form);
return array(
$form_box,
$algo_box,
$info_view,
);
}
}