@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator

Add a Herald action to trigger "Must Encrypt" for mail

Summary: Depends on D18983. Ref T13053. Adds a new Herald action to activate the "must encrypt" flag and drop mail content.

Test Plan:
- Created a new Herald rule:

{F5407075}

- Created a "dog task" (woof woof, unsecure) and a "duck task" (quack quack, secure).
- Viewed mail for both in `bin/mail` and web UI, saw appropriate security/encryption behavior.
- Viewed "Must Encrypt" in "Headers" tab for the duck mail, saw why the mail was encrypted (link to Herald rule).

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13053

Differential Revision: https://secure.phabricator.com/D18984

+111
+2
src/__phutil_library_map__.php
··· 3189 3189 'PhabricatorMailManagementUnverifyWorkflow' => 'applications/metamta/management/PhabricatorMailManagementUnverifyWorkflow.php', 3190 3190 'PhabricatorMailManagementVolumeWorkflow' => 'applications/metamta/management/PhabricatorMailManagementVolumeWorkflow.php', 3191 3191 'PhabricatorMailManagementWorkflow' => 'applications/metamta/management/PhabricatorMailManagementWorkflow.php', 3192 + 'PhabricatorMailMustEncryptHeraldAction' => 'applications/metamta/herald/PhabricatorMailMustEncryptHeraldAction.php', 3192 3193 'PhabricatorMailOutboundMailHeraldAdapter' => 'applications/metamta/herald/PhabricatorMailOutboundMailHeraldAdapter.php', 3193 3194 'PhabricatorMailOutboundRoutingHeraldAction' => 'applications/metamta/herald/PhabricatorMailOutboundRoutingHeraldAction.php', 3194 3195 'PhabricatorMailOutboundRoutingSelfEmailHeraldAction' => 'applications/metamta/herald/PhabricatorMailOutboundRoutingSelfEmailHeraldAction.php', ··· 8674 8675 'PhabricatorMailManagementUnverifyWorkflow' => 'PhabricatorMailManagementWorkflow', 8675 8676 'PhabricatorMailManagementVolumeWorkflow' => 'PhabricatorMailManagementWorkflow', 8676 8677 'PhabricatorMailManagementWorkflow' => 'PhabricatorManagementWorkflow', 8678 + 'PhabricatorMailMustEncryptHeraldAction' => 'HeraldAction', 8677 8679 'PhabricatorMailOutboundMailHeraldAdapter' => 'HeraldAdapter', 8678 8680 'PhabricatorMailOutboundRoutingHeraldAction' => 'HeraldAction', 8679 8681 'PhabricatorMailOutboundRoutingSelfEmailHeraldAction' => 'PhabricatorMailOutboundRoutingHeraldAction',
+14
src/applications/herald/adapter/HeraldAdapter.php
··· 39 39 private $edgeCache = array(); 40 40 private $forbiddenActions = array(); 41 41 private $viewer; 42 + private $mustEncryptReasons = array(); 42 43 43 44 public function getEmailPHIDs() { 44 45 return array_values($this->emailPHIDs); ··· 1180 1181 } 1181 1182 1182 1183 return $this->forbiddenActions[$action]; 1184 + } 1185 + 1186 + 1187 + /* -( Must Encrypt )------------------------------------------------------- */ 1188 + 1189 + 1190 + final public function addMustEncryptReason($reason) { 1191 + $this->mustEncryptReasons[] = $reason; 1192 + return $this; 1193 + } 1194 + 1195 + final public function getMustEncryptReasons() { 1196 + return $this->mustEncryptReasons; 1183 1197 } 1184 1198 1185 1199 }
+9
src/applications/metamta/controller/PhabricatorMetaMTAMailViewController.php
··· 175 175 $properties->addProperty($key, $value); 176 176 } 177 177 178 + $encrypt_phids = $mail->getMustEncryptReasons(); 179 + if ($encrypt_phids) { 180 + $properties->addProperty( 181 + pht('Must Encrypt'), 182 + $viewer->loadHandles($encrypt_phids) 183 + ->renderList()); 184 + } 185 + 186 + 178 187 return $properties; 179 188 } 180 189
+62
src/applications/metamta/herald/PhabricatorMailMustEncryptHeraldAction.php
··· 1 + <?php 2 + 3 + final class PhabricatorMailMustEncryptHeraldAction 4 + extends HeraldAction { 5 + 6 + const DO_MUST_ENCRYPT = 'do.must-encrypt'; 7 + 8 + const ACTIONCONST = 'email.must-encrypt'; 9 + 10 + public function getHeraldActionName() { 11 + return pht('Require secure email'); 12 + } 13 + 14 + public function renderActionDescription($value) { 15 + return pht( 16 + 'Require mail content be transmitted only over secure channels.'); 17 + } 18 + public function supportsObject($object) { 19 + return self::isMailGeneratingObject($object); 20 + } 21 + 22 + public function getActionGroupKey() { 23 + return HeraldUtilityActionGroup::ACTIONGROUPKEY; 24 + } 25 + 26 + public function supportsRuleType($rule_type) { 27 + return ($rule_type != HeraldRuleTypeConfig::RULE_TYPE_PERSONAL); 28 + } 29 + 30 + public function getHeraldActionStandardType() { 31 + return self::STANDARD_NONE; 32 + } 33 + 34 + public function applyEffect($object, HeraldEffect $effect) { 35 + $rule_phid = $effect->getRule()->getPHID(); 36 + 37 + $adapter = $this->getAdapter(); 38 + $adapter->addMustEncryptReason($rule_phid); 39 + 40 + $this->logEffect(self::DO_MUST_ENCRYPT, array($rule_phid)); 41 + } 42 + 43 + protected function getActionEffectMap() { 44 + return array( 45 + self::DO_MUST_ENCRYPT => array( 46 + 'icon' => 'fa-shield', 47 + 'color' => 'blue', 48 + 'name' => pht('Must Encrypt'), 49 + ), 50 + ); 51 + } 52 + 53 + protected function renderActionEffectDescription($type, $data) { 54 + switch ($type) { 55 + case self::DO_MUST_ENCRYPT: 56 + return pht( 57 + 'Made it a requirement that mail content be transmitted only '. 58 + 'over secure channels.'); 59 + } 60 + } 61 + 62 + }
+4
src/applications/metamta/herald/PhabricatorMetaMTAEmailHeraldAction.php
··· 13 13 } 14 14 15 15 public function supportsObject($object) { 16 + return self::isMailGeneratingObject($object); 17 + } 18 + 19 + public static function isMailGeneratingObject($object) { 16 20 // NOTE: This implementation lacks generality, but there's no great way to 17 21 // figure out if something generates email right now. 18 22
+9
src/applications/metamta/storage/PhabricatorMetaMTAMail.php
··· 259 259 return $this->getParam('mustEncrypt', false); 260 260 } 261 261 262 + public function setMustEncryptReasons(array $reasons) { 263 + $this->setParam('mustEncryptReasons', $reasons); 264 + return $this; 265 + } 266 + 267 + public function getMustEncryptReasons() { 268 + return $this->getParam('mustEncryptReasons', array()); 269 + } 270 + 262 271 public function setHTMLBody($html) { 263 272 $this->setParam('html-body', $html); 264 273 return $this;
+11
src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php
··· 71 71 private $mailShouldSend = false; 72 72 private $modularTypes; 73 73 private $silent; 74 + private $mustEncrypt; 74 75 75 76 private $transactionQueue = array(); 76 77 ··· 2549 2550 $this->loadHandles($xactions); 2550 2551 2551 2552 $mail = $this->buildMailForTarget($object, $xactions, $target); 2553 + 2554 + if ($this->mustEncrypt) { 2555 + $mail 2556 + ->setMustEncrypt(true) 2557 + ->setMustEncryptReasons($this->mustEncrypt); 2558 + } 2559 + 2552 2560 } catch (Exception $ex) { 2553 2561 $caught = $ex; 2554 2562 } ··· 3214 3222 $adapter->getQueuedHarbormasterBuildRequests()); 3215 3223 } 3216 3224 3225 + $this->mustEncrypt = $adapter->getMustEncryptReasons(); 3226 + 3217 3227 return array_merge( 3218 3228 $this->didApplyHeraldRules($object, $adapter, $xscript), 3219 3229 $adapter->getQueuedTransactions()); ··· 3558 3568 'feedRelatedPHIDs', 3559 3569 'feedShouldPublish', 3560 3570 'mailShouldSend', 3571 + 'mustEncrypt', 3561 3572 ); 3562 3573 } 3563 3574