@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
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Prevent editing and deleting comments in locked conversations

Summary:
Ref T13289. This tightens up a couple of corner cases around locked threads.

Locking is primarily motivated by two use cases: stopping nonproductive conversations on open source installs (similar to GitHub's feature); and freezing object state for audit/record-keeping purposes.

Currently, you can edit or remove comments on a locked thread, but neither use case is well-served by allowing this. Require "CAN_INTERACT" to edit or remove a comment.

Administrators can still remove comments from a locked thread to serve "lock a flamewar, then clean it up", since "Remove Comment" on a comment you don't own is fairly unambiguously an administrative action.

Test Plan:
- On a locked task, tried to edit and remove my comments as a non-administrator. Saw appropriate disabled UI state and error dialogs (actions were disallowed).
- On a locked task, tried to remove another user's comments as an administrator. This works.
- On a normal task, edited comments normally.

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13289

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

+73 -2
+19
src/applications/transactions/controller/PhabricatorApplicationTransactionCommentEditController.php
··· 31 31 32 32 $done_uri = $obj_handle->getURI(); 33 33 34 + // If an object is locked, you can't edit comments on it. Two reasons to 35 + // lock threads are to calm contentious issues and to freeze state for 36 + // auditing, and editing comments serves neither goal. 37 + 38 + $object = $xaction->getObject(); 39 + $can_interact = PhabricatorPolicyFilter::hasCapability( 40 + $viewer, 41 + $object, 42 + PhabricatorPolicyCapability::CAN_INTERACT); 43 + if (!$can_interact) { 44 + return $this->newDialog() 45 + ->setTitle(pht('Conversation Locked')) 46 + ->appendParagraph( 47 + pht( 48 + 'You can not edit this comment because the conversation is '. 49 + 'locked.')) 50 + ->addCancelButton($done_uri); 51 + } 52 + 34 53 if ($request->isFormOrHisecPost()) { 35 54 $text = $request->getStr('text'); 36 55
+20
src/applications/transactions/controller/PhabricatorApplicationTransactionCommentRemoveController.php
··· 32 32 33 33 $done_uri = $obj_handle->getURI(); 34 34 35 + // We allow administrative removal of comments even if an object is locked, 36 + // so you can lock a flamewar and then go clean it up. Locked threads may 37 + // not otherwise be edited, and non-administrators can not remove comments 38 + // from locked threads. 39 + 40 + $object = $xaction->getObject(); 41 + $can_interact = PhabricatorPolicyFilter::hasCapability( 42 + $viewer, 43 + $object, 44 + PhabricatorPolicyCapability::CAN_INTERACT); 45 + if (!$can_interact && !$viewer->getIsAdmin()) { 46 + return $this->newDialog() 47 + ->setTitle(pht('Conversation Locked')) 48 + ->appendParagraph( 49 + pht( 50 + 'You can not remove this comment because the conversation is '. 51 + 'locked.')) 52 + ->addCancelButton($done_uri); 53 + } 54 + 35 55 if ($request->isFormOrHisecPost()) { 36 56 $comment = $xaction->getApplicationTransactionCommentObject() 37 57 ->setContent('')
+4
src/applications/transactions/editor/PhabricatorApplicationTransactionCommentEditor.php
··· 189 189 $actor, 190 190 $xaction, 191 191 PhabricatorPolicyCapability::CAN_EDIT); 192 + PhabricatorPolicyFilter::requireCapability( 193 + $actor, 194 + $xaction->getObject(), 195 + PhabricatorPolicyCapability::CAN_INTERACT); 192 196 } 193 197 } 194 198
+7
src/applications/transactions/view/PhabricatorApplicationTransactionView.php
··· 505 505 if ($has_edit_capability && !$has_removed_comment) { 506 506 $event->setIsEditable(true); 507 507 } 508 + 508 509 if ($has_edit_capability || $viewer->getIsAdmin()) { 509 510 if (!$has_removed_comment) { 510 511 $event->setIsRemovable(true); 511 512 } 512 513 } 513 514 } 515 + 516 + $can_interact = PhabricatorPolicyFilter::hasCapability( 517 + $viewer, 518 + $xaction->getObject(), 519 + PhabricatorPolicyCapability::CAN_INTERACT); 520 + $event->setCanInteract($can_interact); 514 521 } 515 522 516 523 $comment = $this->renderTransactionContent($xaction);
+23 -2
src/view/phui/PHUITimelineEventView.php
··· 32 32 private $isSilent; 33 33 private $isMFA; 34 34 private $isLockOverride; 35 + private $canInteract; 35 36 36 37 public function setAuthorPHID($author_phid) { 37 38 $this->authorPHID = $author_phid; ··· 112 113 113 114 public function getIsEditable() { 114 115 return $this->isEditable; 116 + } 117 + 118 + public function setCanInteract($can_interact) { 119 + $this->canInteract = $can_interact; 120 + return $this; 121 + } 122 + 123 + public function getCanInteract() { 124 + return $this->canInteract; 115 125 } 116 126 117 127 public function setIsRemovable($is_removable) { ··· 650 660 private function getMenuItems($anchor) { 651 661 $xaction_phid = $this->getTransactionPHID(); 652 662 663 + $can_interact = $this->getCanInteract(); 664 + $viewer = $this->getViewer(); 665 + $is_admin = $viewer->getIsAdmin(); 666 + 653 667 $items = array(); 654 668 655 669 if ($this->getIsEditable()) { ··· 658 672 ->setHref('/transactions/edit/'.$xaction_phid.'/') 659 673 ->setName(pht('Edit Comment')) 660 674 ->addSigil('transaction-edit') 675 + ->setDisabled(!$can_interact) 661 676 ->setMetadata( 662 677 array( 663 678 'anchor' => $anchor, ··· 727 742 $items[] = id(new PhabricatorActionView()) 728 743 ->setType(PhabricatorActionView::TYPE_DIVIDER); 729 744 730 - $items[] = id(new PhabricatorActionView()) 745 + $remove_item = id(new PhabricatorActionView()) 731 746 ->setIcon('fa-trash-o') 732 747 ->setHref('/transactions/remove/'.$xaction_phid.'/') 733 748 ->setName(pht('Remove Comment')) 734 - ->setColor(PhabricatorActionView::RED) 735 749 ->addSigil('transaction-remove') 736 750 ->setMetadata( 737 751 array( 738 752 'anchor' => $anchor, 739 753 )); 740 754 755 + if (!$is_admin && !$can_interact) { 756 + $remove_item->setDisabled(!$is_admin && !$can_interact); 757 + } else { 758 + $remove_item->setColor(PhabricatorActionView::RED); 759 + } 760 + 761 + $items[] = $remove_item; 741 762 } 742 763 743 764 return $items;