@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.

Require "Can Edit" on a build plan to abort or pause associated builds

Summary: Fixes T9614. This is kind of silly, but stop users from fighting turf wars over build resources or showing up on an install and just aborting a bunch of builds for the heck of it.

Test Plan:
- Restarted / paused / aborted / etc builds.
- Tried to do the same for builds I didn't have edit permission on the build plan for, got errors.

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T9614

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

+166 -31
+2
src/applications/harbormaster/controller/HarbormasterBuildActionController.php
··· 39 39 return new Aphront400Response(); 40 40 } 41 41 42 + $build->assertCanIssueCommand($viewer, $action); 43 + 42 44 switch ($via) { 43 45 case 'buildable': 44 46 $return_uri = '/'.$build->getBuildable()->getMonogram();
+23 -4
src/applications/harbormaster/controller/HarbormasterBuildViewController.php
··· 441 441 ->setUser($viewer) 442 442 ->setObject($build); 443 443 444 - $can_restart = $build->canRestartBuild(); 445 - $can_pause = $build->canPauseBuild(); 446 - $can_resume = $build->canResumeBuild(); 447 - $can_abort = $build->canAbortBuild(); 444 + $can_restart = 445 + $build->canRestartBuild() && 446 + $build->canIssueCommand( 447 + $viewer, 448 + HarbormasterBuildCommand::COMMAND_RESTART); 449 + 450 + $can_pause = 451 + $build->canPauseBuild() && 452 + $build->canIssueCommand( 453 + $viewer, 454 + HarbormasterBuildCommand::COMMAND_PAUSE); 455 + 456 + $can_resume = 457 + $build->canResumeBuild() && 458 + $build->canIssueCommand( 459 + $viewer, 460 + HarbormasterBuildCommand::COMMAND_RESUME); 461 + 462 + $can_abort = 463 + $build->canAbortBuild() && 464 + $build->canIssueCommand( 465 + $viewer, 466 + HarbormasterBuildCommand::COMMAND_ABORT); 448 467 449 468 $list->addAction( 450 469 id(new PhabricatorActionView())
+83 -23
src/applications/harbormaster/controller/HarbormasterBuildableActionController.php
··· 51 51 } 52 52 } 53 53 54 + $restricted = false; 55 + foreach ($issuable as $key => $build) { 56 + if (!$build->canIssueCommand($viewer, $action)) { 57 + $restricted = true; 58 + unset($issuable[$key]); 59 + } 60 + } 61 + 54 62 $return_uri = '/'.$buildable->getMonogram(); 55 63 if ($request->isDialogFormPost() && $issuable) { 56 64 $editor = id(new HarbormasterBuildableTransactionEditor()) ··· 84 92 switch ($action) { 85 93 case HarbormasterBuildCommand::COMMAND_RESTART: 86 94 if ($issuable) { 87 - $title = pht('Really restart all builds?'); 88 - $body = pht( 89 - 'Progress on all builds will be discarded, and all builds will '. 90 - 'restart. Side effects of the builds will occur again. Really '. 91 - 'restart all builds?'); 92 - $submit = pht('Restart All Builds'); 95 + $title = pht('Really restart builds?'); 96 + 97 + if ($restricted) { 98 + $body = pht( 99 + 'You only have permission to restart some builds. Progress '. 100 + 'on builds you have permission to restart will be discarded '. 101 + 'and they will restart. Side effects of these builds will '. 102 + 'occur again. Really restart all builds?'); 103 + } else { 104 + $body = pht( 105 + 'Progress on all builds will be discarded, and all builds will '. 106 + 'restart. Side effects of the builds will occur again. Really '. 107 + 'restart all builds?'); 108 + } 109 + 110 + $submit = pht('Restart Builds'); 93 111 } else { 94 112 $title = pht('Unable to Restart Builds'); 95 - $body = pht('No builds can be restarted.'); 113 + 114 + if ($restricted) { 115 + $body = pht('You do not have permission to restart any builds.'); 116 + } else { 117 + $body = pht('No builds can be restarted.'); 118 + } 96 119 } 97 120 break; 98 121 case HarbormasterBuildCommand::COMMAND_PAUSE: 99 122 if ($issuable) { 100 - $title = pht('Really pause all builds?'); 101 - $body = pht( 102 - 'If you pause all builds, work will halt once the current steps '. 103 - 'complete. You can resume the builds later.'); 104 - $submit = pht('Pause All Builds'); 123 + $title = pht('Really pause builds?'); 124 + 125 + if ($restricted) { 126 + $body = pht( 127 + 'You only have permission to pause some builds. Once the '. 128 + 'current steps complete, work will halt on builds you have '. 129 + 'permission to pause. You can resume the builds later.'); 130 + } else { 131 + $body = pht( 132 + 'If you pause all builds, work will halt once the current steps '. 133 + 'complete. You can resume the builds later.'); 134 + } 135 + $submit = pht('Pause Builds'); 105 136 } else { 106 137 $title = pht('Unable to Pause Builds'); 107 - $body = pht('No builds can be paused.'); 138 + 139 + if ($restricted) { 140 + $body = pht('You do not have permission to pause any builds.'); 141 + } else { 142 + $body = pht('No builds can be paused.'); 143 + } 108 144 } 109 145 break; 110 146 case HarbormasterBuildCommand::COMMAND_ABORT: 111 147 if ($issuable) { 112 - $title = pht('Really abort all builds?'); 113 - $body = pht( 114 - 'If you abort all builds, work will halt immediately. Work '. 115 - 'will be discarded, and builds must be completely restarted.'); 116 - $submit = pht('Abort All Builds'); 148 + $title = pht('Really abort builds?'); 149 + if ($restricted) { 150 + $body = pht( 151 + 'You only have permission to abort some builds. Work will '. 152 + 'halt immediately on builds you have permission to abort. '. 153 + 'Progress will be discarded, and builds must be completely '. 154 + 'restarted if you want them to complete.'); 155 + } else { 156 + $body = pht( 157 + 'If you abort all builds, work will halt immediately. Work '. 158 + 'will be discarded, and builds must be completely restarted.'); 159 + } 160 + $submit = pht('Abort Builds'); 117 161 } else { 118 162 $title = pht('Unable to Abort Builds'); 119 - $body = pht('No builds can be aborted.'); 163 + 164 + if ($restricted) { 165 + $body = pht('You do not have permission to abort any builds.'); 166 + } else { 167 + $body = pht('No builds can be aborted.'); 168 + } 120 169 } 121 170 break; 122 171 case HarbormasterBuildCommand::COMMAND_RESUME: 123 172 if ($issuable) { 124 - $title = pht('Really resume all builds?'); 125 - $body = pht('Work will continue on all builds. Really resume?'); 126 - $submit = pht('Resume All Builds'); 173 + $title = pht('Really resume builds?'); 174 + if ($restricted) { 175 + $body = pht( 176 + 'You only have permission to resume some builds. Work will '. 177 + 'continue on builds you have permission to resume.'); 178 + } else { 179 + $body = pht('Work will continue on all builds. Really resume?'); 180 + } 181 + 182 + $submit = pht('Resume Builds'); 127 183 } else { 128 184 $title = pht('Unable to Resume Builds'); 129 - $body = pht('No builds can be resumed.'); 185 + if ($restricted) { 186 + $body = pht('You do not have permission to resume any builds.'); 187 + } else { 188 + $body = pht('No builds can be resumed.'); 189 + } 130 190 } 131 191 break; 132 192 }
+17 -4
src/applications/harbormaster/controller/HarbormasterBuildableViewController.php
··· 86 86 $can_pause = false; 87 87 $can_abort = false; 88 88 89 + $command_restart = HarbormasterBuildCommand::COMMAND_RESTART; 90 + $command_resume = HarbormasterBuildCommand::COMMAND_RESUME; 91 + $command_pause = HarbormasterBuildCommand::COMMAND_PAUSE; 92 + $command_abort = HarbormasterBuildCommand::COMMAND_ABORT; 93 + 89 94 foreach ($buildable->getBuilds() as $build) { 90 95 if ($build->canRestartBuild()) { 91 - $can_restart = true; 96 + if ($build->canIssueCommand($viewer, $command_restart)) { 97 + $can_restart = true; 98 + } 92 99 } 93 100 if ($build->canResumeBuild()) { 94 - $can_resume = true; 101 + if ($build->canIssueCommand($viewer, $command_resume)) { 102 + $can_resume = true; 103 + } 95 104 } 96 105 if ($build->canPauseBuild()) { 97 - $can_pause = true; 106 + if ($build->canIssueCommand($viewer, $command_pause)) { 107 + $can_pause = true; 108 + } 98 109 } 99 110 if ($build->canAbortBuild()) { 100 - $can_abort = true; 111 + if ($build->canIssueCommand($viewer, $command_abort)) { 112 + $can_abort = true; 113 + } 101 114 } 102 115 } 103 116
+5
src/applications/harbormaster/editor/HarbormasterBuildTransactionEditor.php
··· 88 88 return; 89 89 } 90 90 91 + $actor = $this->getActor(); 92 + if (!$build->canIssueCommand($actor, $command)) { 93 + return; 94 + } 95 + 91 96 id(new HarbormasterBuildCommand()) 92 97 ->setAuthorPHID($xaction->getAuthorPHID()) 93 98 ->setTargetPHID($build->getPHID())
+36
src/applications/harbormaster/storage/build/HarbormasterBuild.php
··· 450 450 return $this; 451 451 } 452 452 453 + public function canIssueCommand(PhabricatorUser $viewer, $command) { 454 + try { 455 + $this->assertCanIssueCommand($viewer, $command); 456 + return true; 457 + } catch (Exception $ex) { 458 + return false; 459 + } 460 + } 461 + 462 + public function assertCanIssueCommand(PhabricatorUser $viewer, $command) { 463 + $need_edit = false; 464 + switch ($command) { 465 + case HarbormasterBuildCommand::COMMAND_RESTART: 466 + break; 467 + case HarbormasterBuildCommand::COMMAND_PAUSE: 468 + case HarbormasterBuildCommand::COMMAND_RESUME: 469 + case HarbormasterBuildCommand::COMMAND_ABORT: 470 + $need_edit = true; 471 + break; 472 + default: 473 + throw new Exception( 474 + pht( 475 + 'Invalid Harbormaster build command "%s".', 476 + $command)); 477 + } 478 + 479 + // Issuing these commands requires that you be able to edit the build, to 480 + // prevent enemy engineers from sabotaging your builds. See T9614. 481 + if ($need_edit) { 482 + PhabricatorPolicyFilter::requireCapability( 483 + $viewer, 484 + $this->getBuildPlan(), 485 + PhabricatorPolicyCapability::CAN_EDIT); 486 + } 487 + } 488 + 453 489 454 490 /* -( PhabricatorApplicationTransactionInterface )------------------------- */ 455 491