Page MenuHomePhabricator

D19372.id46337.diff
No OneTemporary

D19372.id46337.diff

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
@@ -4468,6 +4468,7 @@
'PhabricatorTransactionsApplication' => 'applications/transactions/application/PhabricatorTransactionsApplication.php',
'PhabricatorTransactionsDestructionEngineExtension' => 'applications/transactions/engineextension/PhabricatorTransactionsDestructionEngineExtension.php',
'PhabricatorTransactionsFulltextEngineExtension' => 'applications/transactions/engineextension/PhabricatorTransactionsFulltextEngineExtension.php',
+ 'PhabricatorTransactionsHistoryCommand' => 'applications/transactions/command/PhabricatorTransactionsHistoryCommand.php',
'PhabricatorTransformedFile' => 'applications/files/storage/PhabricatorTransformedFile.php',
'PhabricatorTranslationSetting' => 'applications/settings/setting/PhabricatorTranslationSetting.php',
'PhabricatorTranslationsConfigOptions' => 'applications/config/option/PhabricatorTranslationsConfigOptions.php',
@@ -10381,6 +10382,7 @@
'PhabricatorTransactionsApplication' => 'PhabricatorApplication',
'PhabricatorTransactionsDestructionEngineExtension' => 'PhabricatorDestructionEngineExtension',
'PhabricatorTransactionsFulltextEngineExtension' => 'PhabricatorFulltextEngineExtension',
+ 'PhabricatorTransactionsHistoryCommand' => 'MetaMTAEmailTransactionCommand',
'PhabricatorTransformedFile' => 'PhabricatorFileDAO',
'PhabricatorTranslationSetting' => 'PhabricatorOptionGroupSetting',
'PhabricatorTranslationsConfigOptions' => 'PhabricatorApplicationConfigOptions',
diff --git a/src/applications/transactions/command/PhabricatorTransactionsHistoryCommand.php b/src/applications/transactions/command/PhabricatorTransactionsHistoryCommand.php
new file mode 100644
--- /dev/null
+++ b/src/applications/transactions/command/PhabricatorTransactionsHistoryCommand.php
@@ -0,0 +1,47 @@
+<?php
+
+final class PhabricatorTransactionsHistoryCommand
+ extends MetaMTAEmailTransactionCommand {
+
+ public function getCommand() {
+ return 'history';
+ }
+
+ public function getCommandSyntax() {
+ return '**!history**';
+ }
+
+ public function getCommandSummary() {
+ return pht('Review object history via email.');
+ }
+
+ public function getCommandDescription() {
+ return pht(
+ 'Request an email with a complete transaction history for the '.
+ 'object. This is primarily useful if you can not currently access the '.
+ 'web UI because you are a hostile state agent exfiltrating private '.
+ 'corporate data over an unsecured link.');
+ }
+
+ public function isCommandSupportedForObject(
+ PhabricatorApplicationTransactionInterface $object) {
+ return true;
+ }
+
+ public function buildTransactions(
+ PhabricatorUser $viewer,
+ PhabricatorApplicationTransactionInterface $object,
+ PhabricatorMetaMTAReceivedMail $mail,
+ $command,
+ array $argv) {
+
+ $xactions = array();
+
+ $xactions[] = $object->getApplicationTransactionTemplate()
+ ->setTransactionType(PhabricatorTransactions::TYPE_HISTORY)
+ ->setNewValue(true);
+
+ return $xactions;
+ }
+
+}
diff --git a/src/applications/transactions/constants/PhabricatorTransactions.php b/src/applications/transactions/constants/PhabricatorTransactions.php
--- a/src/applications/transactions/constants/PhabricatorTransactions.php
+++ b/src/applications/transactions/constants/PhabricatorTransactions.php
@@ -15,6 +15,7 @@
const TYPE_CREATE = 'core:create';
const TYPE_COLUMNS = 'core:columns';
const TYPE_SUBTYPE = 'core:subtype';
+ const TYPE_HISTORY = 'core:history';
const COLOR_RED = 'red';
const COLOR_ORANGE = 'orange';
diff --git a/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php b/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php
--- a/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php
+++ b/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php
@@ -83,6 +83,7 @@
private $webhookMap = array();
private $transactionQueue = array();
+ private $sendHistory = false;
const STORAGE_ENCODING_BINARY = 'binary';
@@ -300,6 +301,7 @@
$types = array();
$types[] = PhabricatorTransactions::TYPE_CREATE;
+ $types[] = PhabricatorTransactions::TYPE_HISTORY;
if ($this->object instanceof PhabricatorEditEngineSubtypeInterface) {
$types[] = PhabricatorTransactions::TYPE_SUBTYPE;
@@ -377,6 +379,7 @@
switch ($type) {
case PhabricatorTransactions::TYPE_CREATE:
+ case PhabricatorTransactions::TYPE_HISTORY:
return null;
case PhabricatorTransactions::TYPE_SUBTYPE:
return $object->getEditEngineSubtype();
@@ -468,6 +471,7 @@
case PhabricatorTransactions::TYPE_TOKEN:
case PhabricatorTransactions::TYPE_INLINESTATE:
case PhabricatorTransactions::TYPE_SUBTYPE:
+ case PhabricatorTransactions::TYPE_HISTORY:
return $xaction->getNewValue();
case PhabricatorTransactions::TYPE_SPACE:
$space_phid = $xaction->getNewValue();
@@ -520,6 +524,7 @@
switch ($xaction->getTransactionType()) {
case PhabricatorTransactions::TYPE_CREATE:
+ case PhabricatorTransactions::TYPE_HISTORY:
return true;
case PhabricatorTransactions::TYPE_CUSTOMFIELD:
$field = $this->getCustomFieldForTransaction($object, $xaction);
@@ -604,6 +609,7 @@
$field = $this->getCustomFieldForTransaction($object, $xaction);
return $field->applyApplicationTransactionInternalEffects($xaction);
case PhabricatorTransactions::TYPE_CREATE:
+ case PhabricatorTransactions::TYPE_HISTORY:
case PhabricatorTransactions::TYPE_SUBTYPE:
case PhabricatorTransactions::TYPE_TOKEN:
case PhabricatorTransactions::TYPE_VIEW_POLICY:
@@ -665,6 +671,7 @@
$field = $this->getCustomFieldForTransaction($object, $xaction);
return $field->applyApplicationTransactionExternalEffects($xaction);
case PhabricatorTransactions::TYPE_CREATE:
+ case PhabricatorTransactions::TYPE_HISTORY:
case PhabricatorTransactions::TYPE_SUBTYPE:
case PhabricatorTransactions::TYPE_EDGE:
case PhabricatorTransactions::TYPE_TOKEN:
@@ -800,6 +807,9 @@
case PhabricatorTransactions::TYPE_SPACE:
$this->scrambleFileSecrets($object);
break;
+ case PhabricatorTransactions::TYPE_HISTORY:
+ $this->sendHistory = true;
+ break;
}
}
@@ -1317,6 +1327,13 @@
$this->publishFeedStory($object, $xactions, $mailed);
}
+ if ($this->sendHistory) {
+ $history_mail = $this->buildHistoryMail($object);
+ if ($history_mail) {
+ $messages[] = $history_mail;
+ }
+ }
+
// NOTE: This actually sends the mail. We do this last to reduce the chance
// that we send some mail, hit an exception, then send the mail again when
// retrying.
@@ -2557,6 +2574,25 @@
$unexpandable = array();
}
+ $messages = $this->buildMailWithRecipients(
+ $object,
+ $xactions,
+ $email_to,
+ $email_cc,
+ $unexpandable);
+
+ $this->runHeraldMailRules($messages);
+
+ return $messages;
+ }
+
+ private function buildMailWithRecipients(
+ PhabricatorLiskDAO $object,
+ array $xactions,
+ array $email_to,
+ array $email_cc,
+ array $unexpandable) {
+
$targets = $this->buildReplyHandler($object)
->setUnexpandablePHIDs($unexpandable)
->getMailTargets($email_to, $email_cc);
@@ -2603,8 +2639,6 @@
}
}
- $this->runHeraldMailRules($messages);
-
return $messages;
}
@@ -3671,6 +3705,7 @@
'mailMutedPHIDs',
'webhookMap',
'silent',
+ 'sendHistory',
);
}
@@ -4328,4 +4363,32 @@
return true;
}
+ private function buildHistoryMail(PhabricatorLiskDAO $object) {
+ $viewer = $this->requireActor();
+ $recipient_phid = $this->getActingAsPHID();
+
+ // Load every transaction so we can build a mail message with a complete
+ // history for the object.
+ $query = PhabricatorApplicationTransactionQuery::newQueryForObject($object);
+ $xactions = $query
+ ->setViewer($viewer)
+ ->withObjectPHIDs(array($object->getPHID()))
+ ->execute();
+ $xactions = array_reverse($xactions);
+
+ $mail_messages = $this->buildMailWithRecipients(
+ $object,
+ $xactions,
+ array($recipient_phid),
+ array(),
+ array());
+ $mail = head($mail_messages);
+
+ // Since the user explicitly requested "!history", force delivery of this
+ // message regardless of their other mail settings.
+ $mail->setForceDelivery(true);
+
+ return $mail;
+ }
+
}
diff --git a/src/applications/transactions/storage/PhabricatorApplicationTransaction.php b/src/applications/transactions/storage/PhabricatorApplicationTransaction.php
--- a/src/applications/transactions/storage/PhabricatorApplicationTransaction.php
+++ b/src/applications/transactions/storage/PhabricatorApplicationTransaction.php
@@ -545,11 +545,18 @@
return false;
}
+ $xaction_type = $this->getTransactionType();
+
+ // Always hide requests for object history.
+ if ($xaction_type === PhabricatorTransactions::TYPE_HISTORY) {
+ return true;
+ }
+
// Hide creation transactions if the old value is empty. These are
- // transactions like "alice set the task tile to: ...", which are
+ // transactions like "alice set the task title to: ...", which are
// essentially never interesting.
if ($this->getIsCreateTransaction()) {
- switch ($this->getTransactionType()) {
+ switch ($xaction_type) {
case PhabricatorTransactions::TYPE_CREATE:
case PhabricatorTransactions::TYPE_VIEW_POLICY:
case PhabricatorTransactions::TYPE_EDIT_POLICY:

File Metadata

Mime Type
text/plain
Expires
Thu, Mar 20, 3:04 PM (2 w, 7 h ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7713168
Default Alt Text
D19372.id46337.diff (9 KB)

Event Timeline