1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-12-23 05:50:55 +01:00

Update Passphrase for modular transactions

Summary: Updates Passphrase for modular transactions.

Test Plan: Create, edit, lock, view, lots of different types of Passphrases. Enable Conduit, Lock Passphrases, Destroy Secrets from the interface and verify from the DB it was eradicated.

Reviewers: epriestley

Reviewed By: epriestley

Subscribers: Korvin

Differential Revision: https://secure.phabricator.com/D17824
This commit is contained in:
Chad Little 2017-05-04 11:17:47 -07:00
parent d34b338f3f
commit 06eae5578b
17 changed files with 489 additions and 306 deletions

View file

@ -1762,23 +1762,32 @@ phutil_register_library_map(array(
'PassphraseCredential' => 'applications/passphrase/storage/PassphraseCredential.php', 'PassphraseCredential' => 'applications/passphrase/storage/PassphraseCredential.php',
'PassphraseCredentialAuthorPolicyRule' => 'applications/passphrase/policyrule/PassphraseCredentialAuthorPolicyRule.php', 'PassphraseCredentialAuthorPolicyRule' => 'applications/passphrase/policyrule/PassphraseCredentialAuthorPolicyRule.php',
'PassphraseCredentialConduitController' => 'applications/passphrase/controller/PassphraseCredentialConduitController.php', 'PassphraseCredentialConduitController' => 'applications/passphrase/controller/PassphraseCredentialConduitController.php',
'PassphraseCredentialConduitTransaction' => 'applications/passphrase/xaction/PassphraseCredentialConduitTransaction.php',
'PassphraseCredentialControl' => 'applications/passphrase/view/PassphraseCredentialControl.php', 'PassphraseCredentialControl' => 'applications/passphrase/view/PassphraseCredentialControl.php',
'PassphraseCredentialCreateController' => 'applications/passphrase/controller/PassphraseCredentialCreateController.php', 'PassphraseCredentialCreateController' => 'applications/passphrase/controller/PassphraseCredentialCreateController.php',
'PassphraseCredentialDescriptionTransaction' => 'applications/passphrase/xaction/PassphraseCredentialDescriptionTransaction.php',
'PassphraseCredentialDestroyController' => 'applications/passphrase/controller/PassphraseCredentialDestroyController.php', 'PassphraseCredentialDestroyController' => 'applications/passphrase/controller/PassphraseCredentialDestroyController.php',
'PassphraseCredentialDestroyTransaction' => 'applications/passphrase/xaction/PassphraseCredentialDestroyTransaction.php',
'PassphraseCredentialEditController' => 'applications/passphrase/controller/PassphraseCredentialEditController.php', 'PassphraseCredentialEditController' => 'applications/passphrase/controller/PassphraseCredentialEditController.php',
'PassphraseCredentialFulltextEngine' => 'applications/passphrase/search/PassphraseCredentialFulltextEngine.php', 'PassphraseCredentialFulltextEngine' => 'applications/passphrase/search/PassphraseCredentialFulltextEngine.php',
'PassphraseCredentialListController' => 'applications/passphrase/controller/PassphraseCredentialListController.php', 'PassphraseCredentialListController' => 'applications/passphrase/controller/PassphraseCredentialListController.php',
'PassphraseCredentialLockController' => 'applications/passphrase/controller/PassphraseCredentialLockController.php', 'PassphraseCredentialLockController' => 'applications/passphrase/controller/PassphraseCredentialLockController.php',
'PassphraseCredentialLockTransaction' => 'applications/passphrase/xaction/PassphraseCredentialLockTransaction.php',
'PassphraseCredentialLookedAtTransaction' => 'applications/passphrase/xaction/PassphraseCredentialLookedAtTransaction.php',
'PassphraseCredentialNameTransaction' => 'applications/passphrase/xaction/PassphraseCredentialNameTransaction.php',
'PassphraseCredentialPHIDType' => 'applications/passphrase/phid/PassphraseCredentialPHIDType.php', 'PassphraseCredentialPHIDType' => 'applications/passphrase/phid/PassphraseCredentialPHIDType.php',
'PassphraseCredentialPublicController' => 'applications/passphrase/controller/PassphraseCredentialPublicController.php', 'PassphraseCredentialPublicController' => 'applications/passphrase/controller/PassphraseCredentialPublicController.php',
'PassphraseCredentialQuery' => 'applications/passphrase/query/PassphraseCredentialQuery.php', 'PassphraseCredentialQuery' => 'applications/passphrase/query/PassphraseCredentialQuery.php',
'PassphraseCredentialRevealController' => 'applications/passphrase/controller/PassphraseCredentialRevealController.php', 'PassphraseCredentialRevealController' => 'applications/passphrase/controller/PassphraseCredentialRevealController.php',
'PassphraseCredentialSearchEngine' => 'applications/passphrase/query/PassphraseCredentialSearchEngine.php', 'PassphraseCredentialSearchEngine' => 'applications/passphrase/query/PassphraseCredentialSearchEngine.php',
'PassphraseCredentialSecretIDTransaction' => 'applications/passphrase/xaction/PassphraseCredentialSecretIDTransaction.php',
'PassphraseCredentialTransaction' => 'applications/passphrase/storage/PassphraseCredentialTransaction.php', 'PassphraseCredentialTransaction' => 'applications/passphrase/storage/PassphraseCredentialTransaction.php',
'PassphraseCredentialTransactionEditor' => 'applications/passphrase/editor/PassphraseCredentialTransactionEditor.php', 'PassphraseCredentialTransactionEditor' => 'applications/passphrase/editor/PassphraseCredentialTransactionEditor.php',
'PassphraseCredentialTransactionQuery' => 'applications/passphrase/query/PassphraseCredentialTransactionQuery.php', 'PassphraseCredentialTransactionQuery' => 'applications/passphrase/query/PassphraseCredentialTransactionQuery.php',
'PassphraseCredentialTransactionType' => 'applications/passphrase/xaction/PassphraseCredentialTransactionType.php',
'PassphraseCredentialType' => 'applications/passphrase/credentialtype/PassphraseCredentialType.php', 'PassphraseCredentialType' => 'applications/passphrase/credentialtype/PassphraseCredentialType.php',
'PassphraseCredentialTypeTestCase' => 'applications/passphrase/credentialtype/__tests__/PassphraseCredentialTypeTestCase.php', 'PassphraseCredentialTypeTestCase' => 'applications/passphrase/credentialtype/__tests__/PassphraseCredentialTypeTestCase.php',
'PassphraseCredentialUsernameTransaction' => 'applications/passphrase/xaction/PassphraseCredentialUsernameTransaction.php',
'PassphraseCredentialViewController' => 'applications/passphrase/controller/PassphraseCredentialViewController.php', 'PassphraseCredentialViewController' => 'applications/passphrase/controller/PassphraseCredentialViewController.php',
'PassphraseDAO' => 'applications/passphrase/storage/PassphraseDAO.php', 'PassphraseDAO' => 'applications/passphrase/storage/PassphraseDAO.php',
'PassphraseDefaultEditCapability' => 'applications/passphrase/capability/PassphraseDefaultEditCapability.php', 'PassphraseDefaultEditCapability' => 'applications/passphrase/capability/PassphraseDefaultEditCapability.php',
@ -6801,23 +6810,32 @@ phutil_register_library_map(array(
), ),
'PassphraseCredentialAuthorPolicyRule' => 'PhabricatorPolicyRule', 'PassphraseCredentialAuthorPolicyRule' => 'PhabricatorPolicyRule',
'PassphraseCredentialConduitController' => 'PassphraseController', 'PassphraseCredentialConduitController' => 'PassphraseController',
'PassphraseCredentialConduitTransaction' => 'PassphraseCredentialTransactionType',
'PassphraseCredentialControl' => 'AphrontFormControl', 'PassphraseCredentialControl' => 'AphrontFormControl',
'PassphraseCredentialCreateController' => 'PassphraseController', 'PassphraseCredentialCreateController' => 'PassphraseController',
'PassphraseCredentialDescriptionTransaction' => 'PassphraseCredentialTransactionType',
'PassphraseCredentialDestroyController' => 'PassphraseController', 'PassphraseCredentialDestroyController' => 'PassphraseController',
'PassphraseCredentialDestroyTransaction' => 'PassphraseCredentialTransactionType',
'PassphraseCredentialEditController' => 'PassphraseController', 'PassphraseCredentialEditController' => 'PassphraseController',
'PassphraseCredentialFulltextEngine' => 'PhabricatorFulltextEngine', 'PassphraseCredentialFulltextEngine' => 'PhabricatorFulltextEngine',
'PassphraseCredentialListController' => 'PassphraseController', 'PassphraseCredentialListController' => 'PassphraseController',
'PassphraseCredentialLockController' => 'PassphraseController', 'PassphraseCredentialLockController' => 'PassphraseController',
'PassphraseCredentialLockTransaction' => 'PassphraseCredentialTransactionType',
'PassphraseCredentialLookedAtTransaction' => 'PassphraseCredentialTransactionType',
'PassphraseCredentialNameTransaction' => 'PassphraseCredentialTransactionType',
'PassphraseCredentialPHIDType' => 'PhabricatorPHIDType', 'PassphraseCredentialPHIDType' => 'PhabricatorPHIDType',
'PassphraseCredentialPublicController' => 'PassphraseController', 'PassphraseCredentialPublicController' => 'PassphraseController',
'PassphraseCredentialQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'PassphraseCredentialQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PassphraseCredentialRevealController' => 'PassphraseController', 'PassphraseCredentialRevealController' => 'PassphraseController',
'PassphraseCredentialSearchEngine' => 'PhabricatorApplicationSearchEngine', 'PassphraseCredentialSearchEngine' => 'PhabricatorApplicationSearchEngine',
'PassphraseCredentialTransaction' => 'PhabricatorApplicationTransaction', 'PassphraseCredentialSecretIDTransaction' => 'PassphraseCredentialTransactionType',
'PassphraseCredentialTransaction' => 'PhabricatorModularTransaction',
'PassphraseCredentialTransactionEditor' => 'PhabricatorApplicationTransactionEditor', 'PassphraseCredentialTransactionEditor' => 'PhabricatorApplicationTransactionEditor',
'PassphraseCredentialTransactionQuery' => 'PhabricatorApplicationTransactionQuery', 'PassphraseCredentialTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
'PassphraseCredentialTransactionType' => 'PhabricatorModularTransactionType',
'PassphraseCredentialType' => 'Phobject', 'PassphraseCredentialType' => 'Phobject',
'PassphraseCredentialTypeTestCase' => 'PhabricatorTestCase', 'PassphraseCredentialTypeTestCase' => 'PhabricatorTestCase',
'PassphraseCredentialUsernameTransaction' => 'PassphraseCredentialTransactionType',
'PassphraseCredentialViewController' => 'PassphraseController', 'PassphraseCredentialViewController' => 'PassphraseController',
'PassphraseDAO' => 'PhabricatorLiskDAO', 'PassphraseDAO' => 'PhabricatorLiskDAO',
'PassphraseDefaultEditCapability' => 'PhabricatorPolicyCapability', 'PassphraseDefaultEditCapability' => 'PhabricatorPolicyCapability',

View file

@ -50,7 +50,8 @@ final class PassphraseCredentialConduitController
$xactions = array(); $xactions = array();
$xactions[] = id(new PassphraseCredentialTransaction()) $xactions[] = id(new PassphraseCredentialTransaction())
->setTransactionType(PassphraseCredentialTransaction::TYPE_CONDUIT) ->setTransactionType(
PassphraseCredentialConduitTransaction::TRANSACTIONTYPE)
->setNewValue(!$credential->getAllowConduit()); ->setNewValue(!$credential->getAllowConduit());
$editor = id(new PassphraseCredentialTransactionEditor()) $editor = id(new PassphraseCredentialTransactionEditor())

View file

@ -32,7 +32,8 @@ final class PassphraseCredentialDestroyController
$xactions = array(); $xactions = array();
$xactions[] = id(new PassphraseCredentialTransaction()) $xactions[] = id(new PassphraseCredentialTransaction())
->setTransactionType(PassphraseCredentialTransaction::TYPE_DESTROY) ->setTransactionType(
PassphraseCredentialDestroyTransaction::TRANSACTIONTYPE)
->setNewValue(1); ->setNewValue(1);
$editor = id(new PassphraseCredentialTransactionEditor()) $editor = id(new PassphraseCredentialTransactionEditor())

View file

@ -117,12 +117,19 @@ final class PassphraseCredentialEditController extends PassphraseController {
} }
if (!$errors) { if (!$errors) {
$type_name = PassphraseCredentialTransaction::TYPE_NAME; $type_name =
$type_desc = PassphraseCredentialTransaction::TYPE_DESCRIPTION; PassphraseCredentialNameTransaction::TRANSACTIONTYPE;
$type_username = PassphraseCredentialTransaction::TYPE_USERNAME; $type_desc =
$type_destroy = PassphraseCredentialTransaction::TYPE_DESTROY; PassphraseCredentialDescriptionTransaction::TRANSACTIONTYPE;
$type_secret_id = PassphraseCredentialTransaction::TYPE_SECRET_ID; $type_username =
$type_is_locked = PassphraseCredentialTransaction::TYPE_LOCK; PassphraseCredentialUsernameTransaction::TRANSACTIONTYPE;
$type_destroy =
PassphraseCredentialDestroyTransaction::TRANSACTIONTYPE;
$type_secret_id =
PassphraseCredentialSecretIDTransaction::TRANSACTIONTYPE;
$type_is_locked =
PassphraseCredentialLockTransaction::TRANSACTIONTYPE;
$type_view_policy = PhabricatorTransactions::TYPE_VIEW_POLICY; $type_view_policy = PhabricatorTransactions::TYPE_VIEW_POLICY;
$type_edit_policy = PhabricatorTransactions::TYPE_EDIT_POLICY; $type_edit_policy = PhabricatorTransactions::TYPE_EDIT_POLICY;
$type_space = PhabricatorTransactions::TYPE_SPACE; $type_space = PhabricatorTransactions::TYPE_SPACE;

View file

@ -40,11 +40,13 @@ final class PassphraseCredentialLockController
$xactions = array(); $xactions = array();
$xactions[] = id(new PassphraseCredentialTransaction()) $xactions[] = id(new PassphraseCredentialTransaction())
->setTransactionType(PassphraseCredentialTransaction::TYPE_CONDUIT) ->setTransactionType(
PassphraseCredentialConduitTransaction::TRANSACTIONTYPE)
->setNewValue(0); ->setNewValue(0);
$xactions[] = id(new PassphraseCredentialTransaction()) $xactions[] = id(new PassphraseCredentialTransaction())
->setTransactionType(PassphraseCredentialTransaction::TYPE_LOCK) ->setTransactionType(
PassphraseCredentialLockTransaction::TRANSACTIONTYPE)
->setNewValue(1); ->setNewValue(1);
$editor = id(new PassphraseCredentialTransactionEditor()) $editor = id(new PassphraseCredentialTransactionEditor())

View file

@ -67,7 +67,7 @@ final class PassphraseCredentialRevealController
->setDisableWorkflowOnCancel(true) ->setDisableWorkflowOnCancel(true)
->addCancelButton($view_uri, pht('Done')); ->addCancelButton($view_uri, pht('Done'));
$type_secret = PassphraseCredentialTransaction::TYPE_LOOKEDATSECRET; $type_secret = PassphraseCredentialLookedAtTransaction::TRANSACTIONTYPE;
$xactions = array( $xactions = array(
id(new PassphraseCredentialTransaction()) id(new PassphraseCredentialTransaction())
->setTransactionType($type_secret) ->setTransactionType($type_secret)

View file

@ -17,185 +17,15 @@ final class PassphraseCredentialTransactionEditor
$types[] = PhabricatorTransactions::TYPE_VIEW_POLICY; $types[] = PhabricatorTransactions::TYPE_VIEW_POLICY;
$types[] = PhabricatorTransactions::TYPE_EDIT_POLICY; $types[] = PhabricatorTransactions::TYPE_EDIT_POLICY;
$types[] = PassphraseCredentialTransaction::TYPE_NAME;
$types[] = PassphraseCredentialTransaction::TYPE_DESCRIPTION;
$types[] = PassphraseCredentialTransaction::TYPE_USERNAME;
$types[] = PassphraseCredentialTransaction::TYPE_SECRET_ID;
$types[] = PassphraseCredentialTransaction::TYPE_DESTROY;
$types[] = PassphraseCredentialTransaction::TYPE_LOOKEDATSECRET;
$types[] = PassphraseCredentialTransaction::TYPE_LOCK;
$types[] = PassphraseCredentialTransaction::TYPE_CONDUIT;
return $types; return $types;
} }
protected function getCustomTransactionOldValue( public function getCreateObjectTitle($author, $object) {
PhabricatorLiskDAO $object, return pht('%s created this credential.', $author);
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case PassphraseCredentialTransaction::TYPE_NAME:
if ($this->getIsNewObject()) {
return null;
}
return $object->getName();
case PassphraseCredentialTransaction::TYPE_DESCRIPTION:
return $object->getDescription();
case PassphraseCredentialTransaction::TYPE_USERNAME:
return $object->getUsername();
case PassphraseCredentialTransaction::TYPE_SECRET_ID:
return $object->getSecretID();
case PassphraseCredentialTransaction::TYPE_DESTROY:
return (int)$object->getIsDestroyed();
case PassphraseCredentialTransaction::TYPE_LOCK:
return (int)$object->getIsLocked();
case PassphraseCredentialTransaction::TYPE_CONDUIT:
return (int)$object->getAllowConduit();
case PassphraseCredentialTransaction::TYPE_LOOKEDATSECRET:
return null;
}
return parent::getCustomTransactionOldValue($object, $xaction);
} }
protected function getCustomTransactionNewValue( public function getCreateObjectTitleForFeed($author, $object) {
PhabricatorLiskDAO $object, return pht('%s created %s.', $author, $object);
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case PassphraseCredentialTransaction::TYPE_NAME:
case PassphraseCredentialTransaction::TYPE_DESCRIPTION:
case PassphraseCredentialTransaction::TYPE_USERNAME:
case PassphraseCredentialTransaction::TYPE_SECRET_ID:
case PassphraseCredentialTransaction::TYPE_LOOKEDATSECRET:
return $xaction->getNewValue();
case PassphraseCredentialTransaction::TYPE_DESTROY:
case PassphraseCredentialTransaction::TYPE_LOCK:
return (int)$xaction->getNewValue();
case PassphraseCredentialTransaction::TYPE_CONDUIT:
return (int)$xaction->getNewValue();
}
return parent::getCustomTransactionNewValue($object, $xaction);
}
protected function applyCustomInternalTransaction(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case PassphraseCredentialTransaction::TYPE_NAME:
$object->setName($xaction->getNewValue());
return;
case PassphraseCredentialTransaction::TYPE_DESCRIPTION:
$object->setDescription($xaction->getNewValue());
return;
case PassphraseCredentialTransaction::TYPE_USERNAME:
$object->setUsername($xaction->getNewValue());
return;
case PassphraseCredentialTransaction::TYPE_SECRET_ID:
$old_id = $object->getSecretID();
if ($old_id) {
$this->destroySecret($old_id);
}
$object->setSecretID($xaction->getNewValue());
return;
case PassphraseCredentialTransaction::TYPE_DESTROY:
// When destroying a credential, wipe out its secret.
$is_destroyed = $xaction->getNewValue();
$object->setIsDestroyed($is_destroyed);
if ($is_destroyed) {
$secret_id = $object->getSecretID();
if ($secret_id) {
$this->destroySecret($secret_id);
$object->setSecretID(null);
}
}
return;
case PassphraseCredentialTransaction::TYPE_LOOKEDATSECRET:
return;
case PassphraseCredentialTransaction::TYPE_LOCK:
$object->setIsLocked((int)$xaction->getNewValue());
return;
case PassphraseCredentialTransaction::TYPE_CONDUIT:
$object->setAllowConduit((int)$xaction->getNewValue());
return;
}
return parent::applyCustomInternalTransaction($object, $xaction);
}
protected function applyCustomExternalTransaction(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case PassphraseCredentialTransaction::TYPE_NAME:
case PassphraseCredentialTransaction::TYPE_DESCRIPTION:
case PassphraseCredentialTransaction::TYPE_USERNAME:
case PassphraseCredentialTransaction::TYPE_SECRET_ID:
case PassphraseCredentialTransaction::TYPE_DESTROY:
case PassphraseCredentialTransaction::TYPE_LOOKEDATSECRET:
case PassphraseCredentialTransaction::TYPE_LOCK:
case PassphraseCredentialTransaction::TYPE_CONDUIT:
return;
}
return parent::applyCustomExternalTransaction($object, $xaction);
}
private function destroySecret($secret_id) {
$table = new PassphraseSecret();
queryfx(
$table->establishConnection('w'),
'DELETE FROM %T WHERE id = %d',
$table->getTableName(),
$secret_id);
}
protected function validateTransaction(
PhabricatorLiskDAO $object,
$type,
array $xactions) {
$errors = parent::validateTransaction($object, $type, $xactions);
switch ($type) {
case PassphraseCredentialTransaction::TYPE_NAME:
$missing = $this->validateIsEmptyTextField(
$object->getName(),
$xactions);
if ($missing) {
$error = new PhabricatorApplicationTransactionValidationError(
$type,
pht('Required'),
pht('Credential name is required.'),
nonempty(last($xactions), null));
$error->setIsMissingFieldError(true);
$errors[] = $error;
}
break;
case PassphraseCredentialTransaction::TYPE_USERNAME:
$credential_type = $object->getImplementation();
if (!$credential_type->shouldRequireUsername()) {
break;
}
$missing = $this->validateIsEmptyTextField(
$object->getUsername(),
$xactions);
if ($missing) {
$error = new PhabricatorApplicationTransactionValidationError(
$type,
pht('Required'),
pht('Username is required.'),
nonempty(last($xactions), null));
$error->setIsMissingFieldError(true);
$errors[] = $error;
}
break;
}
return $errors;
} }
protected function supportsSearch() { protected function supportsSearch() {

View file

@ -1,16 +1,7 @@
<?php <?php
final class PassphraseCredentialTransaction final class PassphraseCredentialTransaction
extends PhabricatorApplicationTransaction { extends PhabricatorModularTransaction {
const TYPE_NAME = 'passphrase:name';
const TYPE_DESCRIPTION = 'passphrase:description';
const TYPE_USERNAME = 'passphrase:username';
const TYPE_SECRET_ID = 'passphrase:secretID';
const TYPE_DESTROY = 'passphrase:destroy';
const TYPE_LOOKEDATSECRET = 'passphrase:lookedAtSecret';
const TYPE_LOCK = 'passphrase:lock';
const TYPE_CONDUIT = 'passphrase:conduit';
public function getApplicationName() { public function getApplicationName() {
return 'passphrase'; return 'passphrase';
@ -24,116 +15,8 @@ final class PassphraseCredentialTransaction
return null; return null;
} }
public function shouldHide() { public function getBaseTransactionClass() {
$old = $this->getOldValue(); return 'PassphraseCredentialTransactionType';
$new = $this->getNewValue();
switch ($this->getTransactionType()) {
case self::TYPE_DESCRIPTION:
return ($old === null);
case self::TYPE_LOCK:
return ($old === null);
case self::TYPE_USERNAME:
return !strlen($old);
case self::TYPE_LOOKEDATSECRET:
return false;
case self::TYPE_DESTROY:
// Don't show "undestroy" transactions because they're a bit confusing
// and redundant with restoring a secret.
if (!$new) {
return true;
}
}
return parent::shouldHide();
}
public function getTitle() {
$old = $this->getOldValue();
$new = $this->getNewValue();
$author_phid = $this->getAuthorPHID();
switch ($this->getTransactionType()) {
case self::TYPE_NAME:
if ($old === null) {
return pht(
'%s created this credential.',
$this->renderHandleLink($author_phid));
} else {
return pht(
'%s renamed this credential from "%s" to "%s".',
$this->renderHandleLink($author_phid),
$old,
$new);
}
break;
case self::TYPE_DESCRIPTION:
return pht(
'%s updated the description for this credential.',
$this->renderHandleLink($author_phid));
case self::TYPE_USERNAME:
if (strlen($old)) {
return pht(
'%s changed the username for this credential from "%s" to "%s".',
$this->renderHandleLink($author_phid),
$old,
$new);
} else {
return pht(
'%s set the username for this credential to "%s".',
$this->renderHandleLink($author_phid),
$new);
}
break;
case self::TYPE_SECRET_ID:
if ($old === null) {
return pht(
'%s attached a new secret to this credential.',
$this->renderHandleLink($author_phid));
} else {
return pht(
'%s updated the secret for this credential.',
$this->renderHandleLink($author_phid));
}
case self::TYPE_DESTROY:
return pht(
'%s destroyed the secret for this credential.',
$this->renderHandleLink($author_phid));
case self::TYPE_LOOKEDATSECRET:
return pht(
'%s examined the secret plaintext for this credential.',
$this->renderHandleLink($author_phid));
case self::TYPE_LOCK:
return pht(
'%s locked this credential.',
$this->renderHandleLink($author_phid));
case self::TYPE_CONDUIT:
if ($old) {
return pht(
'%s disallowed Conduit API access to this credential.',
$this->renderHandleLink($author_phid));
} else {
return pht(
'%s allowed Conduit API access to this credential.',
$this->renderHandleLink($author_phid));
}
break;
}
return parent::getTitle();
}
public function hasChangeDetails() {
switch ($this->getTransactionType()) {
case self::TYPE_DESCRIPTION:
return true;
}
return parent::hasChangeDetails();
}
public function renderChangeDetails(PhabricatorUser $viewer) {
return $this->renderTextCorpusChangeDetails(
$viewer,
json_encode($this->getOldValue()),
json_encode($this->getNewValue()));
} }
} }

View file

@ -0,0 +1,53 @@
<?php
final class PassphraseCredentialConduitTransaction
extends PassphraseCredentialTransactionType {
const TRANSACTIONTYPE = 'passphrase:conduit';
public function generateOldValue($object) {
return $object->getAllowConduit();
}
public function applyInternalEffects($object, $value) {
$object->setAllowConduit((int)$value);
}
public function getTitle() {
$new = $this->getNewValue();
if ($new) {
return pht(
'%s allowed Conduit API access to this credential.',
$this->renderAuthor());
} else {
return pht(
'%s disallowed Conduit API access to this credential.',
$this->renderAuthor());
}
}
public function getTitleForFeed() {
$new = $this->getNewValue();
if ($new) {
return pht(
'%s allowed Conduit API access to credential %s.',
$this->renderAuthor(),
$this->renderObject());
} else {
return pht(
'%s disallowed Conduit API access to credential %s.',
$this->renderAuthor(),
$this->renderObject());
}
}
public function getIcon() {
$new = $this->getNewValue();
if ($new) {
return 'fa-tty';
} else {
return 'fa-ban';
}
}
}

View file

@ -0,0 +1,64 @@
<?php
final class PassphraseCredentialDescriptionTransaction
extends PassphraseCredentialTransactionType {
const TRANSACTIONTYPE = 'passphrase:description';
public function generateOldValue($object) {
return $object->getDescription();
}
public function applyInternalEffects($object, $value) {
$object->setDescription($value);
}
public function shouldHide() {
$old = $this->getOldValue();
if (!strlen($old)) {
return true;
}
return false;
}
public function getTitle() {
return pht(
'%s updated the description for this credential.',
$this->renderAuthor());
}
public function getTitleForFeed() {
return pht(
'%s updated the description for credential %s.',
$this->renderAuthor(),
$this->renderObject());
}
public function hasChangeDetailView() {
return true;
}
public function getMailDiffSectionHeader() {
return pht('CHANGES TO CREDENTIAL DESCRIPTION');
}
public function newChangeDetailView() {
$viewer = $this->getViewer();
return id(new PhabricatorApplicationTransactionTextDiffDetailView())
->setViewer($viewer)
->setOldText($this->getOldValue())
->setNewText($this->getNewValue());
}
public function newRemarkupChanges() {
$changes = array();
$changes[] = $this->newRemarkupChange()
->setOldValue($this->getOldValue())
->setNewValue($this->getNewValue());
return $changes;
}
}

View file

@ -0,0 +1,52 @@
<?php
final class PassphraseCredentialDestroyTransaction
extends PassphraseCredentialTransactionType {
const TRANSACTIONTYPE = 'passphrase:destroy';
public function generateOldValue($object) {
return $object->getIsDestroyed();
}
public function applyInternalEffects($object, $value) {
$is_destroyed = $value;
$object->setIsDestroyed($is_destroyed);
if ($is_destroyed) {
$secret_id = $object->getSecretID();
if ($secret_id) {
$this->destroySecret($secret_id);
$object->setSecretID(null);
}
}
}
public function shouldHide() {
$new = $this->getNewValue();
if (!$new) {
return true;
}
}
public function getTitle() {
return pht(
'%s destroyed the secret for this credential.',
$this->renderAuthor());
}
public function getTitleForFeed() {
return pht(
'%s destroyed the secret for credential %s.',
$this->renderAuthor(),
$this->renderObject());
}
public function getIcon() {
return 'fa-ban';
}
public function getColor() {
return 'red';
}
}

View file

@ -0,0 +1,41 @@
<?php
final class PassphraseCredentialLockTransaction
extends PassphraseCredentialTransactionType {
const TRANSACTIONTYPE = 'passphrase:lock';
public function generateOldValue($object) {
return $object->getIsLocked();
}
public function applyInternalEffects($object, $value) {
$object->setIsLocked((int)$value);
}
public function shouldHide() {
$new = $this->getNewValue();
if ($new === null) {
return true;
}
return false;
}
public function getTitle() {
return pht(
'%s locked this credential.',
$this->renderAuthor());
}
public function getTitleForFeed() {
return pht(
'%s locked credential %s.',
$this->renderAuthor(),
$this->renderObject());
}
public function getIcon() {
return 'fa-lock';
}
}

View file

@ -0,0 +1,33 @@
<?php
final class PassphraseCredentialLookedAtTransaction
extends PassphraseCredentialTransactionType {
const TRANSACTIONTYPE = 'passphrase:lookedAtSecret';
public function generateOldValue($object) {
return null;
}
public function getTitle() {
return pht(
'%s examined the secret plaintext for this credential.',
$this->renderAuthor());
}
public function getTitleForFeed() {
return pht(
'%s examined the secret plaintext for credential %s.',
$this->renderAuthor(),
$this->renderObject());
}
public function getIcon() {
return 'fa-eye';
}
public function getColor() {
return 'blue';
}
}

View file

@ -0,0 +1,71 @@
<?php
final class PassphraseCredentialNameTransaction
extends PassphraseCredentialTransactionType {
const TRANSACTIONTYPE = 'passphrase:name';
public function generateOldValue($object) {
return $object->getName();
}
public function applyInternalEffects($object, $value) {
$object->setName($value);
}
public function getTitle() {
$old = $this->getOldValue();
if (!strlen($old)) {
return pht(
'%s created this credential.',
$this->renderAuthor());
} else {
return pht(
'%s renamed this credential from %s to %s.',
$this->renderAuthor(),
$this->renderOldValue(),
$this->renderNewValue());
}
}
public function getTitleForFeed() {
$old = $this->getOldValue();
if (!strlen($old)) {
return pht(
'%s created %s.',
$this->renderAuthor(),
$this->renderObject());
} else {
return pht(
'%s renamed %s credential %s to %s.',
$this->renderAuthor(),
$this->renderObject(),
$this->renderOldValue(),
$this->renderNewValue());
}
}
public function validateTransactions($object, array $xactions) {
$errors = array();
if ($this->isEmptyTextTransaction($object->getName(), $xactions)) {
$errors[] = $this->newRequiredError(
pht('Credentials must have a name.'));
}
$max_length = $object->getColumnMaximumByteLength('name');
foreach ($xactions as $xaction) {
$new_value = $xaction->getNewValue();
$new_length = strlen($new_value);
if ($new_length > $max_length) {
$errors[] = $this->newInvalidError(
pht('The name can be no longer than %s characters.',
new PhutilNumber($max_length)));
}
}
return $errors;
}
}

View file

@ -0,0 +1,56 @@
<?php
final class PassphraseCredentialSecretIDTransaction
extends PassphraseCredentialTransactionType {
const TRANSACTIONTYPE = 'passphrase:secretID';
public function generateOldValue($object) {
return $object->getSecretID();
}
public function applyInternalEffects($object, $value) {
$old_id = $object->getSecretID();
if ($old_id) {
$this->destroySecret($old_id);
}
$object->setSecretID($value);
}
public function shouldHide() {
if (!$this->getOldValue()) {
return true;
}
return false;
}
public function getTitle() {
$old = $this->getOldValue();
if ($old === null) {
return pht(
'%s attached a new secret to this credential.',
$this->renderAuthor());
} else {
return pht(
'%s updated the secret for this credential.',
$this->renderAuthor());
}
}
public function getTitleForFeed() {
$old = $this->getOldValue();
if ($old === null) {
return pht(
'%s attached a new secret to %s.',
$this->renderAuthor(),
$this->renderObject());
} else {
return pht(
'%s updated the secret for %s.',
$this->renderAuthor(),
$this->renderObject());
}
}
}

View file

@ -0,0 +1,15 @@
<?php
abstract class PassphraseCredentialTransactionType
extends PhabricatorModularTransactionType {
public function destroySecret($secret_id) {
$table = new PassphraseSecret();
queryfx(
$table->establishConnection('w'),
'DELETE FROM %T WHERE id = %d',
$table->getTableName(),
$secret_id);
}
}

View file

@ -0,0 +1,56 @@
<?php
final class PassphraseCredentialUsernameTransaction
extends PassphraseCredentialTransactionType {
const TRANSACTIONTYPE = 'passphrase:username';
public function generateOldValue($object) {
return $object->getUsername();
}
public function applyInternalEffects($object, $value) {
$object->setUsername($value);
}
public function getTitle() {
return pht(
'%s set the username for this credential to %s.',
$this->renderAuthor(),
$this->renderNewValue());
}
public function getTitleForFeed() {
return pht(
'%s set the username for credential %s to %s.',
$this->renderAuthor(),
$this->renderObject(),
$this->renderNewValue());
}
public function validateTransactions($object, array $xactions) {
$errors = array();
$credential_type = $object->getImplementation();
if ($credential_type->shouldRequireUsername()) {
if ($this->isEmptyTextTransaction($object->getUsername(), $xactions)) {
$errors[] = $this->newRequiredError(
pht('This credential must have a username.'));
}
}
$max_length = $object->getColumnMaximumByteLength('username');
foreach ($xactions as $xaction) {
$new_value = $xaction->getNewValue();
$new_length = strlen($new_value);
if ($new_length > $max_length) {
$errors[] = $this->newInvalidError(
pht('The username can be no longer than %s characters.',
new PhutilNumber($max_length)));
}
}
return $errors;
}
}