3 final class DiffusionSetPasswordSettingsPanel
extends PhabricatorSettingsPanel
{
5 public function isManagementPanel() {
6 if ($this->getUser()->getIsMailingList()) {
13 public function getPanelKey() {
17 public function getPanelName() {
18 return pht('VCS Password');
21 public function getPanelMenuIcon() {
25 public function getPanelGroupKey() {
26 return PhabricatorSettingsAuthenticationPanelGroup
::PANELGROUPKEY
;
29 public function isEnabled() {
30 return PhabricatorEnv
::getEnvConfig('diffusion.allow-http-auth');
33 public function processRequest(AphrontRequest
$request) {
34 $viewer = $request->getUser();
35 $user = $this->getUser();
37 $token = id(new PhabricatorAuthSessionEngine())->requireHighSecuritySession(
42 $vcs_type = PhabricatorAuthPassword
::PASSWORD_TYPE_VCS
;
44 $vcspasswords = id(new PhabricatorAuthPasswordQuery())
46 ->withObjectPHIDs(array($user->getPHID()))
47 ->withPasswordTypes(array($vcs_type))
48 ->withIsRevoked(false)
51 $vcspassword = head($vcspasswords);
53 $vcspassword = PhabricatorAuthPassword
::initializeNewPassword(
58 $panel_uri = $this->getPanelURI('?saved=true');
65 $content_source = PhabricatorContentSource
::newFromRequest($request);
67 // NOTE: This test is against $viewer (not $user), so that the error
68 // message below makes sense in the case that the two are different,
69 // and because an admin reusing their own password is bad, while
70 // system agents generally do not have passwords anyway.
72 $engine = id(new PhabricatorAuthPasswordEngine())
74 ->setContentSource($content_source)
76 ->setPasswordType($vcs_type);
78 if ($request->isFormPost()) {
79 if ($request->getBool('remove')) {
80 if ($vcspassword->getID()) {
81 $vcspassword->delete();
82 return id(new AphrontRedirectResponse())->setURI($panel_uri);
86 $new_password = $request->getStr('password');
87 $confirm = $request->getStr('confirm');
89 $envelope = new PhutilOpaqueEnvelope($new_password);
90 $confirm_envelope = new PhutilOpaqueEnvelope($confirm);
93 $engine->checkNewPassword($envelope, $confirm_envelope);
96 } catch (PhabricatorAuthPasswordException
$ex) {
97 $errors[] = $ex->getMessage();
98 $e_password = $ex->getPasswordError();
99 $e_confirm = $ex->getConfirmError();
104 ->setPassword($envelope, $user)
107 return id(new AphrontRedirectResponse())->setURI($panel_uri);
111 $title = pht('Set VCS Password');
113 $form = id(new AphrontFormView())
115 ->appendRemarkupInstructions(
117 'To access repositories hosted by Phabricator over HTTP, you must '.
118 'set a version control password. This password should be unique.'.
120 "This password applies to all repositories available over ".
123 if ($vcspassword->getID()) {
126 id(new AphrontFormPasswordControl())
127 ->setDisableAutocomplete(true)
128 ->setLabel(pht('Current Password'))
130 ->setValue('********************'));
134 id(new AphrontFormMarkupControl())
135 ->setLabel(pht('Current Password'))
136 ->setValue(phutil_tag('em', array(), pht('No Password Set'))));
141 id(new AphrontFormPasswordControl())
142 ->setDisableAutocomplete(true)
143 ->setName('password')
144 ->setLabel(pht('New VCS Password'))
145 ->setError($e_password))
147 id(new AphrontFormPasswordControl())
148 ->setDisableAutocomplete(true)
150 ->setLabel(pht('Confirm VCS Password'))
151 ->setError($e_confirm))
153 id(new AphrontFormSubmitControl())
154 ->setValue(pht('Change Password')));
157 if (!$vcspassword->getID()) {
158 $is_serious = PhabricatorEnv
::getEnvConfig(
159 'phabricator.serious-business');
161 $suggest = Filesystem
::readRandomBytes(128);
162 $suggest = preg_replace('([^A-Za-z0-9/!().,;{}^&*%~])', '', $suggest);
163 $suggest = substr($suggest, 0, 20);
166 $form->appendRemarkupInstructions(
168 'Having trouble coming up with a good password? Try this randomly '.
169 'generated one, made by a computer:'.
174 $form->appendRemarkupInstructions(
176 'Having trouble coming up with a good password? Try this '.
177 'artisanal password, hand made in small batches by our expert '.
185 $hash_envelope = new PhutilOpaqueEnvelope($vcspassword->getPasswordHash());
188 id(new AphrontFormStaticControl())
189 ->setLabel(pht('Current Algorithm'))
191 PhabricatorPasswordHasher
::getCurrentAlgorithmName($hash_envelope)));
194 id(new AphrontFormStaticControl())
195 ->setLabel(pht('Best Available Algorithm'))
196 ->setValue(PhabricatorPasswordHasher
::getBestAlgorithmName()));
198 if (strlen($hash_envelope->openEnvelope())) {
200 $can_upgrade = PhabricatorPasswordHasher
::canUpgradeHash(
202 } catch (PhabricatorPasswordHasherUnavailableException
$ex) {
203 $can_upgrade = false;
205 'Your VCS password is currently hashed using an algorithm which is '.
206 'no longer available on this install.');
208 'Because the algorithm implementation is missing, your password '.
211 'You can set a new password to replace the old password.');
216 'The strength of your stored VCS password hash can be upgraded. '.
217 'To upgrade, either: use the password to authenticate with a '.
218 'repository; or change your password.');
222 $object_box = id(new PHUIObjectBoxView())
223 ->setHeaderText($title)
224 ->setBackground(PHUIObjectBoxView
::WHITE_CONFIG
)
226 ->setFormErrors($errors);
228 $remove_form = id(new AphrontFormView())
231 if ($vcspassword->getID()) {
233 ->addHiddenInput('remove', true)
234 ->appendRemarkupInstructions(
236 'You can remove your VCS password, which will prevent your '.
237 'account from accessing repositories.'))
239 id(new AphrontFormSubmitControl())
240 ->setValue(pht('Remove Password')));
242 $remove_form->appendRemarkupInstructions(
244 'You do not currently have a VCS password set. If you set one, you '.
245 'can remove it here later.'));
248 $remove_box = id(new PHUIObjectBoxView())
249 ->setHeaderText(pht('Remove VCS Password'))
250 ->setBackground(PHUIObjectBoxView
::WHITE_CONFIG
)
251 ->setForm($remove_form);
254 if ($request->getBool('saved')) {
255 $saved = id(new PHUIInfoView())
256 ->setSeverity(PHUIInfoView
::SEVERITY_NOTICE
)
257 ->setTitle(pht('Password Updated'))
258 ->appendChild(pht('Your VCS password has been updated.'));