Correct a parameter order swap in "diffusion.historyquery" for Mercurial
[phabricator.git] / src / applications / diffusion / panel / DiffusionSetPasswordSettingsPanel.php
blob789adfbf57e0ec4406e8f746c8ce3f6654cb7208
1 <?php
3 final class DiffusionSetPasswordSettingsPanel extends PhabricatorSettingsPanel {
5 public function isManagementPanel() {
6 if ($this->getUser()->getIsMailingList()) {
7 return false;
10 return true;
13 public function getPanelKey() {
14 return 'vcspassword';
17 public function getPanelName() {
18 return pht('VCS Password');
21 public function getPanelMenuIcon() {
22 return 'fa-code';
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(
38 $viewer,
39 $request,
40 '/settings/');
42 $vcs_type = PhabricatorAuthPassword::PASSWORD_TYPE_VCS;
44 $vcspasswords = id(new PhabricatorAuthPasswordQuery())
45 ->setViewer($viewer)
46 ->withObjectPHIDs(array($user->getPHID()))
47 ->withPasswordTypes(array($vcs_type))
48 ->withIsRevoked(false)
49 ->execute();
50 if ($vcspasswords) {
51 $vcspassword = head($vcspasswords);
52 } else {
53 $vcspassword = PhabricatorAuthPassword::initializeNewPassword(
54 $user,
55 $vcs_type);
58 $panel_uri = $this->getPanelURI('?saved=true');
60 $errors = array();
62 $e_password = true;
63 $e_confirm = 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())
73 ->setViewer($viewer)
74 ->setContentSource($content_source)
75 ->setObject($viewer)
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);
92 try {
93 $engine->checkNewPassword($envelope, $confirm_envelope);
94 $e_password = null;
95 $e_confirm = null;
96 } catch (PhabricatorAuthPasswordException $ex) {
97 $errors[] = $ex->getMessage();
98 $e_password = $ex->getPasswordError();
99 $e_confirm = $ex->getConfirmError();
102 if (!$errors) {
103 $vcspassword
104 ->setPassword($envelope, $user)
105 ->save();
107 return id(new AphrontRedirectResponse())->setURI($panel_uri);
111 $title = pht('Set VCS Password');
113 $form = id(new AphrontFormView())
114 ->setUser($viewer)
115 ->appendRemarkupInstructions(
116 pht(
117 'To access repositories hosted by Phabricator over HTTP, you must '.
118 'set a version control password. This password should be unique.'.
119 "\n\n".
120 "This password applies to all repositories available over ".
121 "HTTP."));
123 if ($vcspassword->getID()) {
124 $form
125 ->appendChild(
126 id(new AphrontFormPasswordControl())
127 ->setDisableAutocomplete(true)
128 ->setLabel(pht('Current Password'))
129 ->setDisabled(true)
130 ->setValue('********************'));
131 } else {
132 $form
133 ->appendChild(
134 id(new AphrontFormMarkupControl())
135 ->setLabel(pht('Current Password'))
136 ->setValue(phutil_tag('em', array(), pht('No Password Set'))));
139 $form
140 ->appendChild(
141 id(new AphrontFormPasswordControl())
142 ->setDisableAutocomplete(true)
143 ->setName('password')
144 ->setLabel(pht('New VCS Password'))
145 ->setError($e_password))
146 ->appendChild(
147 id(new AphrontFormPasswordControl())
148 ->setDisableAutocomplete(true)
149 ->setName('confirm')
150 ->setLabel(pht('Confirm VCS Password'))
151 ->setError($e_confirm))
152 ->appendChild(
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);
165 if ($is_serious) {
166 $form->appendRemarkupInstructions(
167 pht(
168 'Having trouble coming up with a good password? Try this randomly '.
169 'generated one, made by a computer:'.
170 "\n\n".
171 "`%s`",
172 $suggest));
173 } else {
174 $form->appendRemarkupInstructions(
175 pht(
176 'Having trouble coming up with a good password? Try this '.
177 'artisanal password, hand made in small batches by our expert '.
178 'craftspeople: '.
179 "\n\n".
180 "`%s`",
181 $suggest));
185 $hash_envelope = new PhutilOpaqueEnvelope($vcspassword->getPasswordHash());
187 $form->appendChild(
188 id(new AphrontFormStaticControl())
189 ->setLabel(pht('Current Algorithm'))
190 ->setValue(
191 PhabricatorPasswordHasher::getCurrentAlgorithmName($hash_envelope)));
193 $form->appendChild(
194 id(new AphrontFormStaticControl())
195 ->setLabel(pht('Best Available Algorithm'))
196 ->setValue(PhabricatorPasswordHasher::getBestAlgorithmName()));
198 if (strlen($hash_envelope->openEnvelope())) {
199 try {
200 $can_upgrade = PhabricatorPasswordHasher::canUpgradeHash(
201 $hash_envelope);
202 } catch (PhabricatorPasswordHasherUnavailableException $ex) {
203 $can_upgrade = false;
204 $errors[] = pht(
205 'Your VCS password is currently hashed using an algorithm which is '.
206 'no longer available on this install.');
207 $errors[] = pht(
208 'Because the algorithm implementation is missing, your password '.
209 'can not be used.');
210 $errors[] = pht(
211 'You can set a new password to replace the old password.');
214 if ($can_upgrade) {
215 $errors[] = pht(
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)
225 ->setForm($form)
226 ->setFormErrors($errors);
228 $remove_form = id(new AphrontFormView())
229 ->setUser($viewer);
231 if ($vcspassword->getID()) {
232 $remove_form
233 ->addHiddenInput('remove', true)
234 ->appendRemarkupInstructions(
235 pht(
236 'You can remove your VCS password, which will prevent your '.
237 'account from accessing repositories.'))
238 ->appendChild(
239 id(new AphrontFormSubmitControl())
240 ->setValue(pht('Remove Password')));
241 } else {
242 $remove_form->appendRemarkupInstructions(
243 pht(
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);
253 $saved = null;
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.'));
261 return array(
262 $saved,
263 $object_box,
264 $remove_box,