diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -1762,23 +1762,32 @@ 'PassphraseCredential' => 'applications/passphrase/storage/PassphraseCredential.php', 'PassphraseCredentialAuthorPolicyRule' => 'applications/passphrase/policyrule/PassphraseCredentialAuthorPolicyRule.php', 'PassphraseCredentialConduitController' => 'applications/passphrase/controller/PassphraseCredentialConduitController.php', + 'PassphraseCredentialConduitTransaction' => 'applications/passphrase/xaction/PassphraseCredentialConduitTransaction.php', 'PassphraseCredentialControl' => 'applications/passphrase/view/PassphraseCredentialControl.php', 'PassphraseCredentialCreateController' => 'applications/passphrase/controller/PassphraseCredentialCreateController.php', + 'PassphraseCredentialDescriptionTransaction' => 'applications/passphrase/xaction/PassphraseCredentialDescriptionTransaction.php', 'PassphraseCredentialDestroyController' => 'applications/passphrase/controller/PassphraseCredentialDestroyController.php', + 'PassphraseCredentialDestroyTransaction' => 'applications/passphrase/xaction/PassphraseCredentialDestroyTransaction.php', 'PassphraseCredentialEditController' => 'applications/passphrase/controller/PassphraseCredentialEditController.php', 'PassphraseCredentialFulltextEngine' => 'applications/passphrase/search/PassphraseCredentialFulltextEngine.php', 'PassphraseCredentialListController' => 'applications/passphrase/controller/PassphraseCredentialListController.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', 'PassphraseCredentialPublicController' => 'applications/passphrase/controller/PassphraseCredentialPublicController.php', 'PassphraseCredentialQuery' => 'applications/passphrase/query/PassphraseCredentialQuery.php', 'PassphraseCredentialRevealController' => 'applications/passphrase/controller/PassphraseCredentialRevealController.php', 'PassphraseCredentialSearchEngine' => 'applications/passphrase/query/PassphraseCredentialSearchEngine.php', + 'PassphraseCredentialSecretIDTransaction' => 'applications/passphrase/xaction/PassphraseCredentialSecretIDTransaction.php', 'PassphraseCredentialTransaction' => 'applications/passphrase/storage/PassphraseCredentialTransaction.php', 'PassphraseCredentialTransactionEditor' => 'applications/passphrase/editor/PassphraseCredentialTransactionEditor.php', 'PassphraseCredentialTransactionQuery' => 'applications/passphrase/query/PassphraseCredentialTransactionQuery.php', + 'PassphraseCredentialTransactionType' => 'applications/passphrase/xaction/PassphraseCredentialTransactionType.php', 'PassphraseCredentialType' => 'applications/passphrase/credentialtype/PassphraseCredentialType.php', 'PassphraseCredentialTypeTestCase' => 'applications/passphrase/credentialtype/__tests__/PassphraseCredentialTypeTestCase.php', + 'PassphraseCredentialUsernameTransaction' => 'applications/passphrase/xaction/PassphraseCredentialUsernameTransaction.php', 'PassphraseCredentialViewController' => 'applications/passphrase/controller/PassphraseCredentialViewController.php', 'PassphraseDAO' => 'applications/passphrase/storage/PassphraseDAO.php', 'PassphraseDefaultEditCapability' => 'applications/passphrase/capability/PassphraseDefaultEditCapability.php', @@ -6801,23 +6810,32 @@ ), 'PassphraseCredentialAuthorPolicyRule' => 'PhabricatorPolicyRule', 'PassphraseCredentialConduitController' => 'PassphraseController', + 'PassphraseCredentialConduitTransaction' => 'PassphraseCredentialTransactionType', 'PassphraseCredentialControl' => 'AphrontFormControl', 'PassphraseCredentialCreateController' => 'PassphraseController', + 'PassphraseCredentialDescriptionTransaction' => 'PassphraseCredentialTransactionType', 'PassphraseCredentialDestroyController' => 'PassphraseController', + 'PassphraseCredentialDestroyTransaction' => 'PassphraseCredentialTransactionType', 'PassphraseCredentialEditController' => 'PassphraseController', 'PassphraseCredentialFulltextEngine' => 'PhabricatorFulltextEngine', 'PassphraseCredentialListController' => 'PassphraseController', 'PassphraseCredentialLockController' => 'PassphraseController', + 'PassphraseCredentialLockTransaction' => 'PassphraseCredentialTransactionType', + 'PassphraseCredentialLookedAtTransaction' => 'PassphraseCredentialTransactionType', + 'PassphraseCredentialNameTransaction' => 'PassphraseCredentialTransactionType', 'PassphraseCredentialPHIDType' => 'PhabricatorPHIDType', 'PassphraseCredentialPublicController' => 'PassphraseController', 'PassphraseCredentialQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'PassphraseCredentialRevealController' => 'PassphraseController', 'PassphraseCredentialSearchEngine' => 'PhabricatorApplicationSearchEngine', - 'PassphraseCredentialTransaction' => 'PhabricatorApplicationTransaction', + 'PassphraseCredentialSecretIDTransaction' => 'PassphraseCredentialTransactionType', + 'PassphraseCredentialTransaction' => 'PhabricatorModularTransaction', 'PassphraseCredentialTransactionEditor' => 'PhabricatorApplicationTransactionEditor', 'PassphraseCredentialTransactionQuery' => 'PhabricatorApplicationTransactionQuery', + 'PassphraseCredentialTransactionType' => 'PhabricatorModularTransactionType', 'PassphraseCredentialType' => 'Phobject', 'PassphraseCredentialTypeTestCase' => 'PhabricatorTestCase', + 'PassphraseCredentialUsernameTransaction' => 'PassphraseCredentialTransactionType', 'PassphraseCredentialViewController' => 'PassphraseController', 'PassphraseDAO' => 'PhabricatorLiskDAO', 'PassphraseDefaultEditCapability' => 'PhabricatorPolicyCapability', diff --git a/src/applications/passphrase/controller/PassphraseCredentialConduitController.php b/src/applications/passphrase/controller/PassphraseCredentialConduitController.php --- a/src/applications/passphrase/controller/PassphraseCredentialConduitController.php +++ b/src/applications/passphrase/controller/PassphraseCredentialConduitController.php @@ -50,7 +50,8 @@ $xactions = array(); $xactions[] = id(new PassphraseCredentialTransaction()) - ->setTransactionType(PassphraseCredentialTransaction::TYPE_CONDUIT) + ->setTransactionType( + PassphraseCredentialConduitTransaction::TRANSACTIONTYPE) ->setNewValue(!$credential->getAllowConduit()); $editor = id(new PassphraseCredentialTransactionEditor()) diff --git a/src/applications/passphrase/controller/PassphraseCredentialDestroyController.php b/src/applications/passphrase/controller/PassphraseCredentialDestroyController.php --- a/src/applications/passphrase/controller/PassphraseCredentialDestroyController.php +++ b/src/applications/passphrase/controller/PassphraseCredentialDestroyController.php @@ -32,7 +32,8 @@ $xactions = array(); $xactions[] = id(new PassphraseCredentialTransaction()) - ->setTransactionType(PassphraseCredentialTransaction::TYPE_DESTROY) + ->setTransactionType( + PassphraseCredentialDestroyTransaction::TRANSACTIONTYPE) ->setNewValue(1); $editor = id(new PassphraseCredentialTransactionEditor()) diff --git a/src/applications/passphrase/controller/PassphraseCredentialEditController.php b/src/applications/passphrase/controller/PassphraseCredentialEditController.php --- a/src/applications/passphrase/controller/PassphraseCredentialEditController.php +++ b/src/applications/passphrase/controller/PassphraseCredentialEditController.php @@ -117,12 +117,19 @@ } if (!$errors) { - $type_name = PassphraseCredentialTransaction::TYPE_NAME; - $type_desc = PassphraseCredentialTransaction::TYPE_DESCRIPTION; - $type_username = PassphraseCredentialTransaction::TYPE_USERNAME; - $type_destroy = PassphraseCredentialTransaction::TYPE_DESTROY; - $type_secret_id = PassphraseCredentialTransaction::TYPE_SECRET_ID; - $type_is_locked = PassphraseCredentialTransaction::TYPE_LOCK; + $type_name = + PassphraseCredentialNameTransaction::TRANSACTIONTYPE; + $type_desc = + PassphraseCredentialDescriptionTransaction::TRANSACTIONTYPE; + $type_username = + PassphraseCredentialUsernameTransaction::TRANSACTIONTYPE; + $type_destroy = + PassphraseCredentialDestroyTransaction::TRANSACTIONTYPE; + $type_secret_id = + PassphraseCredentialSecretIDTransaction::TRANSACTIONTYPE; + $type_is_locked = + PassphraseCredentialLockTransaction::TRANSACTIONTYPE; + $type_view_policy = PhabricatorTransactions::TYPE_VIEW_POLICY; $type_edit_policy = PhabricatorTransactions::TYPE_EDIT_POLICY; $type_space = PhabricatorTransactions::TYPE_SPACE; diff --git a/src/applications/passphrase/controller/PassphraseCredentialLockController.php b/src/applications/passphrase/controller/PassphraseCredentialLockController.php --- a/src/applications/passphrase/controller/PassphraseCredentialLockController.php +++ b/src/applications/passphrase/controller/PassphraseCredentialLockController.php @@ -40,11 +40,13 @@ $xactions = array(); $xactions[] = id(new PassphraseCredentialTransaction()) - ->setTransactionType(PassphraseCredentialTransaction::TYPE_CONDUIT) + ->setTransactionType( + PassphraseCredentialConduitTransaction::TRANSACTIONTYPE) ->setNewValue(0); $xactions[] = id(new PassphraseCredentialTransaction()) - ->setTransactionType(PassphraseCredentialTransaction::TYPE_LOCK) + ->setTransactionType( + PassphraseCredentialLockTransaction::TRANSACTIONTYPE) ->setNewValue(1); $editor = id(new PassphraseCredentialTransactionEditor()) diff --git a/src/applications/passphrase/controller/PassphraseCredentialRevealController.php b/src/applications/passphrase/controller/PassphraseCredentialRevealController.php --- a/src/applications/passphrase/controller/PassphraseCredentialRevealController.php +++ b/src/applications/passphrase/controller/PassphraseCredentialRevealController.php @@ -67,7 +67,7 @@ ->setDisableWorkflowOnCancel(true) ->addCancelButton($view_uri, pht('Done')); - $type_secret = PassphraseCredentialTransaction::TYPE_LOOKEDATSECRET; + $type_secret = PassphraseCredentialLookedAtTransaction::TRANSACTIONTYPE; $xactions = array( id(new PassphraseCredentialTransaction()) ->setTransactionType($type_secret) diff --git a/src/applications/passphrase/editor/PassphraseCredentialTransactionEditor.php b/src/applications/passphrase/editor/PassphraseCredentialTransactionEditor.php --- a/src/applications/passphrase/editor/PassphraseCredentialTransactionEditor.php +++ b/src/applications/passphrase/editor/PassphraseCredentialTransactionEditor.php @@ -17,185 +17,15 @@ $types[] = PhabricatorTransactions::TYPE_VIEW_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; } - protected function getCustomTransactionOldValue( - PhabricatorLiskDAO $object, - 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( - 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_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); + public function getCreateObjectTitle($author, $object) { + return pht('%s created this credential.', $author); } - 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; + public function getCreateObjectTitleForFeed($author, $object) { + return pht('%s created %s.', $author, $object); } protected function supportsSearch() { diff --git a/src/applications/passphrase/storage/PassphraseCredentialTransaction.php b/src/applications/passphrase/storage/PassphraseCredentialTransaction.php --- a/src/applications/passphrase/storage/PassphraseCredentialTransaction.php +++ b/src/applications/passphrase/storage/PassphraseCredentialTransaction.php @@ -1,16 +1,7 @@ getOldValue(); - $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())); + public function getBaseTransactionClass() { + return 'PassphraseCredentialTransactionType'; } } diff --git a/src/applications/passphrase/xaction/PassphraseCredentialConduitTransaction.php b/src/applications/passphrase/xaction/PassphraseCredentialConduitTransaction.php new file mode 100644 --- /dev/null +++ b/src/applications/passphrase/xaction/PassphraseCredentialConduitTransaction.php @@ -0,0 +1,53 @@ +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'; + } + } + +} diff --git a/src/applications/passphrase/xaction/PassphraseCredentialDescriptionTransaction.php b/src/applications/passphrase/xaction/PassphraseCredentialDescriptionTransaction.php new file mode 100644 --- /dev/null +++ b/src/applications/passphrase/xaction/PassphraseCredentialDescriptionTransaction.php @@ -0,0 +1,64 @@ +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; + } + +} diff --git a/src/applications/passphrase/xaction/PassphraseCredentialDestroyTransaction.php b/src/applications/passphrase/xaction/PassphraseCredentialDestroyTransaction.php new file mode 100644 --- /dev/null +++ b/src/applications/passphrase/xaction/PassphraseCredentialDestroyTransaction.php @@ -0,0 +1,52 @@ +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'; + } + +} diff --git a/src/applications/passphrase/xaction/PassphraseCredentialLockTransaction.php b/src/applications/passphrase/xaction/PassphraseCredentialLockTransaction.php new file mode 100644 --- /dev/null +++ b/src/applications/passphrase/xaction/PassphraseCredentialLockTransaction.php @@ -0,0 +1,41 @@ +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'; + } + +} diff --git a/src/applications/passphrase/xaction/PassphraseCredentialLookedAtTransaction.php b/src/applications/passphrase/xaction/PassphraseCredentialLookedAtTransaction.php new file mode 100644 --- /dev/null +++ b/src/applications/passphrase/xaction/PassphraseCredentialLookedAtTransaction.php @@ -0,0 +1,33 @@ +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'; + } + +} diff --git a/src/applications/passphrase/xaction/PassphraseCredentialNameTransaction.php b/src/applications/passphrase/xaction/PassphraseCredentialNameTransaction.php new file mode 100644 --- /dev/null +++ b/src/applications/passphrase/xaction/PassphraseCredentialNameTransaction.php @@ -0,0 +1,71 @@ +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; + } + +} diff --git a/src/applications/passphrase/xaction/PassphraseCredentialSecretIDTransaction.php b/src/applications/passphrase/xaction/PassphraseCredentialSecretIDTransaction.php new file mode 100644 --- /dev/null +++ b/src/applications/passphrase/xaction/PassphraseCredentialSecretIDTransaction.php @@ -0,0 +1,56 @@ +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()); + } + } + +} diff --git a/src/applications/passphrase/xaction/PassphraseCredentialTransactionType.php b/src/applications/passphrase/xaction/PassphraseCredentialTransactionType.php new file mode 100644 --- /dev/null +++ b/src/applications/passphrase/xaction/PassphraseCredentialTransactionType.php @@ -0,0 +1,15 @@ +establishConnection('w'), + 'DELETE FROM %T WHERE id = %d', + $table->getTableName(), + $secret_id); + } + +} diff --git a/src/applications/passphrase/xaction/PassphraseCredentialUsernameTransaction.php b/src/applications/passphrase/xaction/PassphraseCredentialUsernameTransaction.php new file mode 100644 --- /dev/null +++ b/src/applications/passphrase/xaction/PassphraseCredentialUsernameTransaction.php @@ -0,0 +1,56 @@ +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; + } + +}