1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-30 02:32:42 +01:00

When users resign from revisions, stop expanding projects/packages to include them

Summary:
Depends on D19019. Ref T13053. Fixes T12689. See PHI178.

Currently, if `@alice` resigns from a revision but `#alice-fan-club` is still a subscriber or reviewer, she'll continue to get mail. This is undesirable.

When users are associated with an object but have explicitly disengaged in an individal role (currently, only resign in audit/differential) mark them "unexpandable", so that they can no longer be included through implicit membership in a group (a project or package).

`@alice` can still get mail if she's a explicit recipient: as an author, owner, or if she adds herself back as a subscriber.

Test Plan:
  - Added `@ducker` and `#users-named-ducker` as reviewers. Ducker got mail.
  - Resigned as ducker, stopped getting future mail.
  - Subscribed explicitly, got mail again.
  - (Plus some `var_dump()` sanity checking in the internals.)

Reviewers: amckinley

Maniphest Tasks: T13053, T12689

Differential Revision: https://secure.phabricator.com/D19021
This commit is contained in:
epriestley 2018-02-07 07:08:36 -08:00
parent f214abb63f
commit 1cd3a59378
7 changed files with 88 additions and 5 deletions

View file

@ -496,7 +496,6 @@ final class PhabricatorAuditEditor
$phids[] = $object->getAuthorPHID(); $phids[] = $object->getAuthorPHID();
} }
$status_resigned = PhabricatorAuditStatusConstants::RESIGNED;
foreach ($object->getAudits() as $audit) { foreach ($object->getAudits() as $audit) {
if (!$audit->isInteresting()) { if (!$audit->isInteresting()) {
// Don't send mail to uninteresting auditors, like packages which // Don't send mail to uninteresting auditors, like packages which
@ -504,7 +503,7 @@ final class PhabricatorAuditEditor
continue; continue;
} }
if ($audit->getAuditStatus() != $status_resigned) { if (!$audit->isResigned()) {
$phids[] = $audit->getAuditorPHID(); $phids[] = $audit->getAuditorPHID();
} }
} }
@ -514,6 +513,18 @@ final class PhabricatorAuditEditor
return $phids; return $phids;
} }
protected function newMailUnexpandablePHIDs(PhabricatorLiskDAO $object) {
$phids = array();
foreach ($object->getAudits() as $auditor) {
if ($auditor->isResigned()) {
$phids[] = $auditor->getAuditorPHID();
}
}
return $phids;
}
protected function buildMailBody( protected function buildMailBody(
PhabricatorLiskDAO $object, PhabricatorLiskDAO $object,
array $xactions) { array $xactions) {

View file

@ -644,6 +644,18 @@ final class DifferentialTransactionEditor
return $phids; return $phids;
} }
protected function newMailUnexpandablePHIDs(PhabricatorLiskDAO $object) {
$phids = array();
foreach ($object->getReviewers() as $reviewer) {
if ($reviewer->isResigned()) {
$phids[] = $reviewer->getReviewerPHID();
}
}
return $phids;
}
protected function getMailAction( protected function getMailAction(
PhabricatorLiskDAO $object, PhabricatorLiskDAO $object,
array $xactions) { array $xactions) {

View file

@ -820,9 +820,15 @@ final class DifferentialRevision extends DifferentialDAO
} }
foreach ($reviewers as $reviewer) { foreach ($reviewers as $reviewer) {
if ($reviewer->getReviewerPHID() == $phid) { if ($reviewer->getReviewerPHID() !== $phid) {
return true; continue;
} }
if ($reviewer->isResigned()) {
continue;
}
return true;
} }
return false; return false;

View file

@ -6,6 +6,7 @@ abstract class PhabricatorMailReplyHandler extends Phobject {
private $applicationEmail; private $applicationEmail;
private $actor; private $actor;
private $excludePHIDs = array(); private $excludePHIDs = array();
private $unexpandablePHIDs = array();
final public function setMailReceiver($mail_receiver) { final public function setMailReceiver($mail_receiver) {
$this->validateMailReceiver($mail_receiver); $this->validateMailReceiver($mail_receiver);
@ -45,6 +46,15 @@ abstract class PhabricatorMailReplyHandler extends Phobject {
return $this->excludePHIDs; return $this->excludePHIDs;
} }
public function setUnexpandablePHIDs(array $phids) {
$this->unexpandablePHIDs = $phids;
return $this;
}
public function getUnexpandablePHIDs() {
return $this->unexpandablePHIDs;
}
abstract public function validateMailReceiver($mail_receiver); abstract public function validateMailReceiver($mail_receiver);
abstract public function getPrivateReplyHandlerEmailAddress( abstract public function getPrivateReplyHandlerEmailAddress(
PhabricatorUser $user); PhabricatorUser $user);
@ -297,6 +307,16 @@ abstract class PhabricatorMailReplyHandler extends Phobject {
$to_result = array(); $to_result = array();
$cc_result = array(); $cc_result = array();
// "Unexpandable" users have disengaged from an object (for example,
// by resigning from a revision).
// If such a user is still a direct recipient (for example, they're still
// on the Subscribers list) they're fair game, but group targets (like
// projects) will no longer include them when expanded.
$unexpandable = $this->getUnexpandablePHIDs();
$unexpandable = array_fuse($unexpandable);
$all_phids = array_merge($to, $cc); $all_phids = array_merge($to, $cc);
if ($all_phids) { if ($all_phids) {
$map = id(new PhabricatorMetaMTAMemberQuery()) $map = id(new PhabricatorMetaMTAMemberQuery())
@ -305,11 +325,21 @@ abstract class PhabricatorMailReplyHandler extends Phobject {
->execute(); ->execute();
foreach ($to as $phid) { foreach ($to as $phid) {
foreach ($map[$phid] as $expanded) { foreach ($map[$phid] as $expanded) {
if ($expanded !== $phid) {
if (isset($unexpandable[$expanded])) {
continue;
}
}
$to_result[$expanded] = $expanded; $to_result[$expanded] = $expanded;
} }
} }
foreach ($cc as $phid) { foreach ($cc as $phid) {
foreach ($map[$phid] as $expanded) { foreach ($map[$phid] as $expanded) {
if ($expanded !== $phid) {
if (isset($unexpandable[$expanded])) {
continue;
}
}
$cc_result[$expanded] = $expanded; $cc_result[$expanded] = $expanded;
} }
} }

View file

@ -72,6 +72,15 @@ final class PhabricatorRepositoryAuditRequest
return true; return true;
} }
public function isResigned() {
switch ($this->getAuditStatus()) {
case PhabricatorAuditStatusConstants::RESIGNED:
return true;
}
return false;
}
/* -( PhabricatorPolicyInterface )----------------------------------------- */ /* -( PhabricatorPolicyInterface )----------------------------------------- */

View file

@ -657,7 +657,8 @@ final class PhabricatorRepositoryCommit
public function isAutomaticallySubscribed($phid) { public function isAutomaticallySubscribed($phid) {
// TODO: This should also list auditors, but handling that is a bit messy // TODO: This should also list auditors, but handling that is a bit messy
// right now because we are not guaranteed to have the data. // right now because we are not guaranteed to have the data. (It should not
// include resigned auditors.)
return ($phid == $this->getAuthorPHID()); return ($phid == $this->getAuthorPHID());
} }

View file

@ -77,6 +77,7 @@ abstract class PhabricatorApplicationTransactionEditor
private $oldTo = array(); private $oldTo = array();
private $oldCC = array(); private $oldCC = array();
private $mailRemovedPHIDs = array(); private $mailRemovedPHIDs = array();
private $mailUnexpandablePHIDs = array();
private $transactionQueue = array(); private $transactionQueue = array();
@ -1204,6 +1205,7 @@ abstract class PhabricatorApplicationTransactionEditor
$this->mailShouldSend = true; $this->mailShouldSend = true;
$this->mailToPHIDs = $this->getMailTo($object); $this->mailToPHIDs = $this->getMailTo($object);
$this->mailCCPHIDs = $this->getMailCC($object); $this->mailCCPHIDs = $this->getMailCC($object);
$this->mailUnexpandablePHIDs = $this->newMailUnexpandablePHIDs($object);
// Add any recipients who were previously on the notification list // Add any recipients who were previously on the notification list
// but were removed by this change. // but were removed by this change.
@ -2562,7 +2564,13 @@ abstract class PhabricatorApplicationTransactionEditor
$email_cc = $this->mailCCPHIDs; $email_cc = $this->mailCCPHIDs;
$email_cc = array_merge($email_cc, $this->heraldEmailPHIDs); $email_cc = array_merge($email_cc, $this->heraldEmailPHIDs);
$unexpandable = $this->mailUnexpandablePHIDs;
if (!is_array($unexpandable)) {
$unexpandable = array();
}
$targets = $this->buildReplyHandler($object) $targets = $this->buildReplyHandler($object)
->setUnexpandablePHIDs($unexpandable)
->getMailTargets($email_to, $email_cc); ->getMailTargets($email_to, $email_cc);
// Set this explicitly before we start swapping out the effective actor. // Set this explicitly before we start swapping out the effective actor.
@ -2817,6 +2825,11 @@ abstract class PhabricatorApplicationTransactionEditor
} }
protected function newMailUnexpandablePHIDs(PhabricatorLiskDAO $object) {
return array();
}
/** /**
* @task mail * @task mail
*/ */
@ -3617,6 +3630,7 @@ abstract class PhabricatorApplicationTransactionEditor
'mailShouldSend', 'mailShouldSend',
'mustEncrypt', 'mustEncrypt',
'mailStamps', 'mailStamps',
'mailUnexpandablePHIDs',
); );
} }