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:
parent
f214abb63f
commit
1cd3a59378
7 changed files with 88 additions and 5 deletions
|
@ -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) {
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 )----------------------------------------- */
|
||||||
|
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
|
@ -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',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue