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

Modernize some Harbormaster Controller/Policy infrastructure

Summary:
Ref T8095. This is just general groundwork for more exciting changes:

- Use more modern conventions around controllers, UI elements, and dialogs.
- Provide real CAN_EDIT policies and policy checks (they just don't do anything yet).

Test Plan:
- Used all affected controllers.
- Faked CAN_EDIT to POLICY_NOONE and verified everything was greyed out and unselectable.

Reviewers: btrahan

Reviewed By: btrahan

Subscribers: epriestley

Maniphest Tasks: T8095

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

+148 -146
-17
src/applications/harbormaster/controller/HarbormasterController.php
··· 2 2 3 3 abstract class HarbormasterController extends PhabricatorController { 4 4 5 - protected function buildApplicationCrumbs() { 6 - $crumbs = parent::buildApplicationCrumbs(); 7 - 8 - $can_create = $this->hasApplicationCapability( 9 - HarbormasterManagePlansCapability::CAPABILITY); 10 - 11 - $crumbs->addAction( 12 - id(new PHUIListItemView()) 13 - ->setName(pht('New Build Plan')) 14 - ->setHref($this->getApplicationURI('plan/edit/')) 15 - ->setDisabled(!$can_create) 16 - ->setWorkflow(!$can_create) 17 - ->setIcon('fa-plus-square')); 18 - 19 - return $crumbs; 20 - } 21 - 22 5 }
+9 -14
src/applications/harbormaster/controller/HarbormasterPlanDisableController.php
··· 3 3 final class HarbormasterPlanDisableController 4 4 extends HarbormasterPlanController { 5 5 6 - private $id; 7 - 8 - public function willProcessRequest(array $data) { 9 - $this->id = $data['id']; 10 - } 11 - 12 - public function processRequest() { 13 - $request = $this->getRequest(); 14 - $viewer = $request->getUser(); 6 + public function handleRequest(AphrontRequest $request) { 7 + $viewer = $this->getViewer(); 15 8 16 9 $this->requireApplicationCapability( 17 10 HarbormasterManagePlansCapability::CAPABILITY); 18 11 19 12 $plan = id(new HarbormasterBuildPlanQuery()) 20 13 ->setViewer($viewer) 21 - ->withIDs(array($this->id)) 14 + ->withIDs(array($request->getURIData('id'))) 15 + ->requireCapabilities( 16 + array( 17 + PhabricatorPolicyCapability::CAN_VIEW, 18 + PhabricatorPolicyCapability::CAN_EDIT, 19 + )) 22 20 ->executeOne(); 23 21 if (!$plan) { 24 22 return new Aphront404Response(); ··· 63 61 $button = pht('Disable Plan'); 64 62 } 65 63 66 - $dialog = id(new AphrontDialogView()) 67 - ->setUser($viewer) 64 + return $this->newDialog() 68 65 ->setTitle($title) 69 66 ->appendChild($body) 70 67 ->addSubmitButton($button) 71 68 ->addCancelButton($plan_uri); 72 - 73 - return id(new AphrontDialogResponse())->setDialog($dialog); 74 69 } 75 70 76 71 }
+11 -11
src/applications/harbormaster/controller/HarbormasterPlanEditController.php
··· 2 2 3 3 final class HarbormasterPlanEditController extends HarbormasterPlanController { 4 4 5 - private $id; 6 - 7 - public function willProcessRequest(array $data) { 8 - $this->id = idx($data, 'id'); 9 - } 10 - 11 - public function processRequest() { 12 - $request = $this->getRequest(); 13 - $viewer = $request->getUser(); 5 + public function handleRequest(AphrontRequest $request) { 6 + $viewer = $this->getViewer(); 14 7 15 8 $this->requireApplicationCapability( 16 9 HarbormasterManagePlansCapability::CAPABILITY); 17 10 18 - if ($this->id) { 11 + $id = $request->getURIData('id'); 12 + if ($id) { 19 13 $plan = id(new HarbormasterBuildPlanQuery()) 20 14 ->setViewer($viewer) 21 - ->withIDs(array($this->id)) 15 + ->withIDs(array($id)) 16 + ->requireCapabilities( 17 + array( 18 + PhabricatorPolicyCapability::CAN_VIEW, 19 + PhabricatorPolicyCapability::CAN_EDIT, 20 + )) 22 21 ->executeOne(); 23 22 if (!$plan) { 24 23 return new Aphront404Response(); ··· 43 42 44 43 $editor = id(new HarbormasterBuildPlanEditor()) 45 44 ->setActor($viewer) 45 + ->setContinueOnNoEffect(true) 46 46 ->setContentSourceFromRequest($request); 47 47 48 48 try {
+20 -8
src/applications/harbormaster/controller/HarbormasterPlanListController.php
··· 2 2 3 3 final class HarbormasterPlanListController extends HarbormasterPlanController { 4 4 5 - private $queryKey; 6 - 7 5 public function shouldAllowPublic() { 8 6 return true; 9 7 } 10 8 11 - public function willProcessRequest(array $data) { 12 - $this->queryKey = idx($data, 'queryKey'); 13 - } 14 - 15 - public function processRequest() { 9 + public function handleRequest(AphrontRequest $request) { 16 10 $controller = id(new PhabricatorApplicationSearchController()) 17 - ->setQueryKey($this->queryKey) 11 + ->setQueryKey($request->getURIData('queryKey')) 18 12 ->setSearchEngine(new HarbormasterBuildPlanSearchEngine()) 19 13 ->setNavigation($this->buildSideNavView()); 20 14 ··· 43 37 public function buildApplicationMenu() { 44 38 return $this->buildSideNavView(true)->getMenu(); 45 39 } 40 + 41 + protected function buildApplicationCrumbs() { 42 + $crumbs = parent::buildApplicationCrumbs(); 43 + 44 + $can_create = $this->hasApplicationCapability( 45 + HarbormasterManagePlansCapability::CAPABILITY); 46 + 47 + $crumbs->addAction( 48 + id(new PHUIListItemView()) 49 + ->setName(pht('New Build Plan')) 50 + ->setHref($this->getApplicationURI('plan/edit/')) 51 + ->setDisabled(!$can_create) 52 + ->setWorkflow(!$can_create) 53 + ->setIcon('fa-plus-square')); 54 + 55 + return $crumbs; 56 + } 57 + 46 58 47 59 }
+9 -14
src/applications/harbormaster/controller/HarbormasterPlanRunController.php
··· 2 2 3 3 final class HarbormasterPlanRunController extends HarbormasterController { 4 4 5 - private $id; 6 - 7 - public function willProcessRequest(array $data) { 8 - $this->id = $data['id']; 9 - } 10 - 11 - public function processRequest() { 12 - $request = $this->getRequest(); 13 - $viewer = $request->getUser(); 5 + public function handleRequest(AphrontRequest $request) { 6 + $viewer = $this->getViewer(); 14 7 15 8 $this->requireApplicationCapability( 16 9 HarbormasterManagePlansCapability::CAPABILITY); 17 10 18 - $plan_id = $this->id; 11 + $plan_id = $request->getURIData('id'); 12 + 13 + // NOTE: At least for now, this only requires the "Can Manage Plans" 14 + // capability, not the "Can Edit" capability. Possibly it should have 15 + // a more stringent requirement, though. 16 + 19 17 $plan = id(new HarbormasterBuildPlanQuery()) 20 18 ->setViewer($viewer) 21 19 ->withIDs(array($plan_id)) ··· 87 85 ->setError($e_name) 88 86 ->setValue($v_name)); 89 87 90 - $dialog = id(new AphrontDialogView()) 88 + return $this->newDialog() 91 89 ->setWidth(AphrontDialogView::WIDTH_FULL) 92 - ->setUser($viewer) 93 90 ->setTitle($title) 94 91 ->appendChild($form) 95 92 ->addCancelButton($cancel_uri) 96 93 ->addSubmitButton($save_button); 97 - 98 - return id(new AphrontDialogResponse())->setDialog($dialog); 99 94 } 100 95 101 96 }
+45 -28
src/applications/harbormaster/controller/HarbormasterPlanViewController.php
··· 2 2 3 3 final class HarbormasterPlanViewController extends HarbormasterPlanController { 4 4 5 - private $id; 5 + public function handleRequest(AphrontRequest $request) { 6 + $viewer = $this->getviewer(); 6 7 7 - public function willProcessRequest(array $data) { 8 - $this->id = $data['id']; 9 - } 10 - 11 - public function processRequest() { 12 - $request = $this->getRequest(); 13 - $viewer = $request->getUser(); 14 - 15 - $id = $this->id; 8 + $id = $request->getURIData('id'); 16 9 17 10 $plan = id(new HarbormasterBuildPlanQuery()) 18 11 ->setViewer($viewer) ··· 79 72 } 80 73 81 74 private function buildStepList(HarbormasterBuildPlan $plan) { 82 - $request = $this->getRequest(); 83 - $viewer = $request->getUser(); 75 + $viewer = $this->getViewer(); 84 76 85 - $run_order = 86 - HarbormasterBuildGraph::determineDependencyExecution($plan); 77 + $run_order = HarbormasterBuildGraph::determineDependencyExecution($plan); 87 78 88 79 $steps = id(new HarbormasterBuildStepQuery()) 89 80 ->setViewer($viewer) ··· 91 82 ->execute(); 92 83 $steps = mpull($steps, null, 'getPHID'); 93 84 94 - $can_edit = $this->hasApplicationCapability( 85 + $has_manage = $this->hasApplicationCapability( 95 86 HarbormasterManagePlansCapability::CAPABILITY); 87 + 88 + $has_edit = PhabricatorPolicyFilter::hasCapability( 89 + $viewer, 90 + $plan, 91 + PhabricatorPolicyCapability::CAN_EDIT); 92 + 93 + $can_edit = ($has_manage && $has_edit); 96 94 97 95 $step_list = id(new PHUIObjectItemListView()) 98 96 ->setUser($viewer) ··· 222 220 $step_list->addItem($item); 223 221 } 224 222 225 - return array($step_list, $has_any_conflicts, $is_deadlocking); 223 + $step_list->setFlush(true); 224 + 225 + $plan_id = $plan->getID(); 226 + 227 + $header = id(new PHUIHeaderView()) 228 + ->setHeader(pht('Build Steps')) 229 + ->addActionLink( 230 + id(new PHUIButtonView()) 231 + ->setText(pht('Add Build Step')) 232 + ->setHref($this->getApplicationURI("step/add/{$plan_id}/")) 233 + ->setTag('a') 234 + ->setIcon( 235 + id(new PHUIIconView()) 236 + ->setIconFont('fa-plus')) 237 + ->setDisabled(!$can_edit) 238 + ->setWorkflow(true)); 239 + 240 + $step_box = id(new PHUIObjectBoxView()) 241 + ->setHeader($header) 242 + ->appendChild($step_list); 243 + 244 + return array($step_box, $has_any_conflicts, $is_deadlocking); 226 245 } 227 246 228 247 private function buildActionList(HarbormasterBuildPlan $plan) { 229 - $request = $this->getRequest(); 230 - $viewer = $request->getUser(); 248 + $viewer = $this->getViewer(); 231 249 $id = $plan->getID(); 232 250 233 251 $list = id(new PhabricatorActionListView()) ··· 235 253 ->setObject($plan) 236 254 ->setObjectURI($this->getApplicationURI("plan/{$id}/")); 237 255 238 - $can_edit = $this->hasApplicationCapability( 256 + $has_manage = $this->hasApplicationCapability( 239 257 HarbormasterManagePlansCapability::CAPABILITY); 258 + 259 + $has_edit = PhabricatorPolicyFilter::hasCapability( 260 + $viewer, 261 + $plan, 262 + PhabricatorPolicyCapability::CAN_EDIT); 263 + 264 + $can_edit = ($has_manage && $has_edit); 240 265 241 266 $list->addAction( 242 267 id(new PhabricatorActionView()) ··· 266 291 267 292 $list->addAction( 268 293 id(new PhabricatorActionView()) 269 - ->setName(pht('Add Build Step')) 270 - ->setHref($this->getApplicationURI("step/add/{$id}/")) 271 - ->setWorkflow(true) 272 - ->setDisabled(!$can_edit) 273 - ->setIcon('fa-plus')); 274 - 275 - $list->addAction( 276 - id(new PhabricatorActionView()) 277 294 ->setName(pht('Run Plan Manually')) 278 295 ->setHref($this->getApplicationURI("plan/run/{$id}/")) 279 296 ->setWorkflow(true) 280 - ->setDisabled(!$can_edit) 297 + ->setDisabled(!$has_manage) 281 298 ->setIcon('fa-play-circle')); 282 299 283 300 return $list;
+8 -10
src/applications/harbormaster/controller/HarbormasterStepAddController.php
··· 2 2 3 3 final class HarbormasterStepAddController extends HarbormasterController { 4 4 5 - private $id; 6 - 7 - public function willProcessRequest(array $data) { 8 - $this->id = $data['id']; 9 - } 10 - 11 - public function processRequest() { 12 - $request = $this->getRequest(); 13 - $viewer = $request->getUser(); 5 + public function handleRequest(AphrontRequest $request) { 6 + $viewer = $this->getViewer(); 14 7 15 8 $this->requireApplicationCapability( 16 9 HarbormasterManagePlansCapability::CAPABILITY); 17 10 18 11 $plan = id(new HarbormasterBuildPlanQuery()) 19 12 ->setViewer($viewer) 20 - ->withIDs(array($this->id)) 13 + ->withIDs(array($request->getURIData('id'))) 14 + ->requireCapabilities( 15 + array( 16 + PhabricatorPolicyCapability::CAN_VIEW, 17 + PhabricatorPolicyCapability::CAN_EDIT, 18 + )) 21 19 ->executeOne(); 22 20 if (!$plan) { 23 21 return new Aphront404Response();
+16 -23
src/applications/harbormaster/controller/HarbormasterStepDeleteController.php
··· 2 2 3 3 final class HarbormasterStepDeleteController extends HarbormasterController { 4 4 5 - private $id; 6 - 7 - public function willProcessRequest(array $data) { 8 - $this->id = $data['id']; 9 - } 10 - 11 - public function processRequest() { 12 - $request = $this->getRequest(); 13 - $viewer = $request->getUser(); 5 + public function handleRequest(AphrontRequest $request) { 6 + $viewer = $this->getViewer(); 14 7 15 8 $this->requireApplicationCapability( 16 9 HarbormasterManagePlansCapability::CAPABILITY); 17 10 18 - $id = $this->id; 11 + $id = $request->getURIData('id'); 19 12 20 13 $step = id(new HarbormasterBuildStepQuery()) 21 14 ->setViewer($viewer) 22 15 ->withIDs(array($id)) 16 + ->requireCapabilities( 17 + array( 18 + PhabricatorPolicyCapability::CAN_VIEW, 19 + PhabricatorPolicyCapability::CAN_EDIT, 20 + )) 23 21 ->executeOne(); 24 - if ($step === null) { 25 - throw new Exception(pht('Build step not found!')); 22 + if (!$step) { 23 + return new Aphront404Response(); 26 24 } 27 25 28 26 $plan_id = $step->getBuildPlan()->getID(); ··· 33 31 return id(new AphrontRedirectResponse())->setURI($done_uri); 34 32 } 35 33 36 - $dialog = new AphrontDialogView(); 37 - $dialog->setTitle(pht('Really Delete Step?')) 38 - ->setUser($viewer) 39 - ->addSubmitButton(pht('Delete Build Step')) 40 - ->addCancelButton($done_uri); 41 - $dialog->appendChild( 42 - phutil_tag( 43 - 'p', 44 - array(), 34 + return $this->newDialog() 35 + ->setTitle(pht('Really Delete Step?')) 36 + ->appendParagraph( 45 37 pht( 46 38 "Are you sure you want to delete this step? ". 47 - "This can't be undone!"))); 48 - return id(new AphrontDialogResponse())->setDialog($dialog); 39 + "This can't be undone!")) 40 + ->addCancelButton($done_uri) 41 + ->addSubmitButton(pht('Delete Build Step')); 49 42 } 50 43 51 44 }
+23 -21
src/applications/harbormaster/controller/HarbormasterStepEditController.php
··· 2 2 3 3 final class HarbormasterStepEditController extends HarbormasterController { 4 4 5 - private $id; 6 - private $planID; 7 - private $className; 8 - 9 - public function willProcessRequest(array $data) { 10 - $this->id = idx($data, 'id'); 11 - $this->planID = idx($data, 'plan'); 12 - $this->className = idx($data, 'class'); 13 - } 14 - 15 - public function processRequest() { 16 - $request = $this->getRequest(); 17 - $viewer = $request->getUser(); 5 + public function handleRequest(AphrontRequest $request) { 6 + $viewer = $this->getViewer(); 18 7 19 8 $this->requireApplicationCapability( 20 9 HarbormasterManagePlansCapability::CAPABILITY); 21 10 22 - if ($this->id) { 11 + $id = $request->getURIData('id'); 12 + if ($id) { 23 13 $step = id(new HarbormasterBuildStepQuery()) 24 14 ->setViewer($viewer) 25 - ->withIDs(array($this->id)) 15 + ->withIDs(array($id)) 16 + ->requireCapabilities( 17 + array( 18 + PhabricatorPolicyCapability::CAN_VIEW, 19 + PhabricatorPolicyCapability::CAN_EDIT, 20 + )) 26 21 ->executeOne(); 27 22 if (!$step) { 28 23 return new Aphront404Response(); ··· 31 26 32 27 $is_new = false; 33 28 } else { 29 + $plan_id = $request->getURIData('plan'); 30 + $class = $request->getURIData('class'); 31 + 34 32 $plan = id(new HarbormasterBuildPlanQuery()) 35 - ->setViewer($viewer) 36 - ->withIDs(array($this->planID)) 37 - ->executeOne(); 33 + ->setViewer($viewer) 34 + ->withIDs(array($plan_id)) 35 + ->requireCapabilities( 36 + array( 37 + PhabricatorPolicyCapability::CAN_VIEW, 38 + PhabricatorPolicyCapability::CAN_EDIT, 39 + )) 40 + ->executeOne(); 38 41 if (!$plan) { 39 42 return new Aphront404Response(); 40 43 } 41 44 42 - $impl = HarbormasterBuildStepImplementation::getImplementation( 43 - $this->className); 45 + $impl = HarbormasterBuildStepImplementation::getImplementation($class); 44 46 if (!$impl) { 45 47 return new Aphront404Response(); 46 48 } 47 49 48 50 $step = HarbormasterBuildStep::initializeNewStep($viewer) 49 51 ->setBuildPlanPHID($plan->getPHID()) 50 - ->setClassName($this->className); 52 + ->setClassName($class); 51 53 52 54 $is_new = true; 53 55 }
+6
src/applications/harbormaster/storage/configuration/HarbormasterBuildPlan.php
··· 102 102 public function getCapabilities() { 103 103 return array( 104 104 PhabricatorPolicyCapability::CAN_VIEW, 105 + PhabricatorPolicyCapability::CAN_EDIT, 105 106 ); 106 107 } 107 108 ··· 109 110 switch ($capability) { 110 111 case PhabricatorPolicyCapability::CAN_VIEW: 111 112 return PhabricatorPolicies::getMostOpenPolicy(); 113 + case PhabricatorPolicyCapability::CAN_EDIT: 114 + // NOTE: In practice, this policy is always limited by the "Mangage 115 + // Build Plans" policy. 116 + return PhabricatorPolicies::getMostOpenPolicy(); 112 117 } 113 118 } 114 119 ··· 119 124 public function describeAutomaticCapability($capability) { 120 125 return null; 121 126 } 127 + 122 128 }
+1
src/applications/harbormaster/storage/configuration/HarbormasterBuildStep.php
··· 118 118 public function getCapabilities() { 119 119 return array( 120 120 PhabricatorPolicyCapability::CAN_VIEW, 121 + PhabricatorPolicyCapability::CAN_EDIT, 121 122 ); 122 123 } 123 124