Page MenuHomePhabricator

Add a "Lock Permanently" action to Passphrase
ClosedPublic

Authored by lpriestley on May 2 2014, 6:37 AM.
Tags
None
Referenced Files
Unknown Object (File)
Mon, Apr 29, 2:16 PM
Unknown Object (File)
Wed, Apr 24, 10:04 PM
Unknown Object (File)
Mon, Apr 8, 12:16 AM
Unknown Object (File)
Mar 29 2024, 3:54 PM
Unknown Object (File)
Mar 27 2024, 1:53 PM
Unknown Object (File)
Mar 23 2024, 5:39 PM
Unknown Object (File)
Feb 7 2024, 6:40 PM
Unknown Object (File)
Feb 7 2024, 6:40 PM
Subscribers

Details

Summary

Fixes T4931. Each new credential should come with the ability to lock the credential permanently, so that no one can ever edit again. Each existing credential must allow user to lock existing credential.

Test Plan

Create new credential, verify that you can lock it before saving it. Open existing unlocked credential, verify that option to lock it exists. Once credential is locked, the option to reveal it should be disabled, and editing the credential won't allow username/password updates.

Diff Detail

Repository
rP Phabricator
Lint
Lint Skipped
Unit
Tests Skipped

Event Timeline

lpriestley retitled this revision from to Add a "Lock Permanently" action to Passphrase.
lpriestley updated this object.
lpriestley edited the test plan for this revision. (Show Details)
lpriestley added a reviewer: epriestley.
epriestley edited edge metadata.

Handful of minor things inline, but this looks generally correct to me.

src/applications/passphrase/controller/PassphraseCredentialDestroyController.php
63–69

Locking a credential does not need to prevent it from being destroyed -- you should still be able to destroy it, just not read it.

src/applications/passphrase/controller/PassphraseCredentialEditController.php
152–174

When a credential is locked, we should prevent the actual changes from being applied here.

Right now if I'm editing a locked credential the "secret" input will be disabled, but I can control-click the document, find the textarea, deleted the disabled="disabled" attribute, and then use the form normally -- even if the credential is locked.

Instead, we should only build the $type_is_locked, $type_destroy and $type_secret_id transactions if the credential is not locked. Then even if a user removes the "disabled" attribute they still can not edit the secret.

That is, the code should look something like:

$xactions[] = name;
if (!$credential->getIsLocked()) {
  $xactions[] = username;
  $xactions[] = secret;
  $xactions[] = locked;
}
256–264

If the credential is locked, it might be nice to appendRemarkupInstructions() here with a message like "This credential is permanently locked and can not be edited.", to explain why the controls are disabled.

279–284

Let's only show this if the credential is being created. The major reason for this convenience checkbox is that some workflows (like creating a new repository in Diffusion) create credentials using this form as a popup dialog, while you're in the middle of some other workflow -- so once you're done, you don't end up on the credential detail page, but back in the middle of creating a repository or whatever. In these cases it would be inconvenient to navigate to the credential page in order to lock the credential.

You can test $is_new to see if the credential is being freshly created vs edited.

src/applications/passphrase/controller/PassphraseCredentialLockController.php
71–72

This block should move above the $request->isFormPost() test on line 37.

Currently, you can control-click the document and edit things a bit (this is a little involved) and produce a submit button. Then you click that and end up with an isFormPost() request, which will get you into the if ($request->isFormPost()) block and let you take the action.

In this case, taking the action multiple times doesn't matter, but as a general rule it's better to put a check like this earlier, so the main action of the controller is completely unreachable.

82–96

As a recently-introduced optional convenience, you can now replace this longer dialog style:

$dialog = id(new AphrontDialogView())
  ->setUser($viewer)
  ->...;
return id(new AphrontDialogResponse())->setDialog($dialog);

...with this slightly shorter, less boilerplatey style:

return $this->newDialog()
  ->...;

...provided $this is a PhabricatorController (when you want to build a dialog, it almost always is).

src/applications/passphrase/controller/PassphraseCredentialRevealController.php
94–100

This is correct, but should move above the $request->isFormPost() call on line 37.

This revision now requires changes to proceed.May 2 2014, 1:30 PM
lpriestley edited edge metadata.

Addressing code review

epriestley edited edge metadata.

Caught one minor logical issue and two tiny nitpicks, I'm just going to tweak those in the pull. Thanks!

src/applications/passphrase/controller/PassphraseCredentialEditController.php
178–179

I think this is the wrong check (getIsLocked() vs !getIsLocked()) and we can just skip all of these transactions (including $type_destroy, which un-destroys credentials) for locked secrets. Basically just remove this line and the closing brace on 161, so all this stuff is covered by the !getisLocked() check?

269–270

You should concatenate inside pht(), because it's easier for a translator to translate the full string than part of the string. That is, instead of doing this:

pht('a').pht('b')

...this is usually better:

pht('a'.'b')

The static analysis stuff is smart enough to figure out 'a'.'b', but can't combine the other form in the general case.

src/applications/passphrase/controller/PassphraseCredentialLockController.php
71–72

This has no actual impact, but should move above line 37 for consistency.

This revision is now accepted and ready to land.May 3 2014, 1:20 AM
epriestley updated this revision to Diff 21261.

Closed by commit rPd7b7b1933793 (authored by @lpriestley, committed by @epriestley).