mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-10 00:42:41 +01:00
Make event-triggered actions more aware of application access
Summary: Fixes T3675. - Maniphest had a couple of old non-event listeners; move them to events. - Make most of the similar listeners a little more similar. - Add checks for access to the application. Test Plan: - Viewed profile, project, task, revision. - Clicked all the actions. - Blocked access to various applications and verified the actions vanished. Reviewers: btrahan Reviewed By: btrahan CC: aran Maniphest Tasks: T3675 Differential Revision: https://secure.phabricator.com/D7365
This commit is contained in:
parent
d66972c9f2
commit
8994a81b35
16 changed files with 277 additions and 118 deletions
|
@ -297,7 +297,7 @@ phutil_register_library_map(array(
|
|||
'DefaultDatabaseConfigurationProvider' => 'infrastructure/storage/configuration/DefaultDatabaseConfigurationProvider.php',
|
||||
'DifferentialAction' => 'applications/differential/constants/DifferentialAction.php',
|
||||
'DifferentialActionHasNoEffectException' => 'applications/differential/exception/DifferentialActionHasNoEffectException.php',
|
||||
'DifferentialActionMenuEventListener' => 'applications/differential/events/DifferentialActionMenuEventListener.php',
|
||||
'DifferentialActionMenuEventListener' => 'applications/differential/event/DifferentialActionMenuEventListener.php',
|
||||
'DifferentialAddCommentView' => 'applications/differential/view/DifferentialAddCommentView.php',
|
||||
'DifferentialAffectedPath' => 'applications/differential/storage/DifferentialAffectedPath.php',
|
||||
'DifferentialApplyPatchFieldSpecification' => 'applications/differential/field/specification/DifferentialApplyPatchFieldSpecification.php',
|
||||
|
@ -368,7 +368,7 @@ phutil_register_library_map(array(
|
|||
'DifferentialFreeformFieldTestCase' => 'applications/differential/field/specification/__tests__/DifferentialFreeformFieldTestCase.php',
|
||||
'DifferentialGitSVNIDFieldSpecification' => 'applications/differential/field/specification/DifferentialGitSVNIDFieldSpecification.php',
|
||||
'DifferentialHostFieldSpecification' => 'applications/differential/field/specification/DifferentialHostFieldSpecification.php',
|
||||
'DifferentialHovercardEventListener' => 'applications/differential/events/DifferentialHovercardEventListener.php',
|
||||
'DifferentialHovercardEventListener' => 'applications/differential/event/DifferentialHovercardEventListener.php',
|
||||
'DifferentialHunk' => 'applications/differential/storage/DifferentialHunk.php',
|
||||
'DifferentialHunkParser' => 'applications/differential/parser/DifferentialHunkParser.php',
|
||||
'DifferentialHunkParserTestCase' => 'applications/differential/parser/__tests__/DifferentialHunkParserTestCase.php',
|
||||
|
@ -1876,6 +1876,7 @@ phutil_register_library_map(array(
|
|||
'PhluxVariableEditor' => 'applications/phlux/editor/PhluxVariableEditor.php',
|
||||
'PhluxVariableQuery' => 'applications/phlux/query/PhluxVariableQuery.php',
|
||||
'PhluxViewController' => 'applications/phlux/controller/PhluxViewController.php',
|
||||
'PholioActionMenuEventListener' => 'applications/pholio/event/PholioActionMenuEventListener.php',
|
||||
'PholioConstants' => 'applications/pholio/constants/PholioConstants.php',
|
||||
'PholioController' => 'applications/pholio/controller/PholioController.php',
|
||||
'PholioDAO' => 'applications/pholio/storage/PholioDAO.php',
|
||||
|
@ -4122,6 +4123,7 @@ phutil_register_library_map(array(
|
|||
'PhluxVariableEditor' => 'PhabricatorApplicationTransactionEditor',
|
||||
'PhluxVariableQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||
'PhluxViewController' => 'PhluxController',
|
||||
'PholioActionMenuEventListener' => 'PhabricatorEventListener',
|
||||
'PholioController' => 'PhabricatorController',
|
||||
'PholioDAO' => 'PhabricatorLiskDAO',
|
||||
'PholioImage' =>
|
||||
|
|
|
@ -14,24 +14,32 @@ final class AuditActionMenuEventListener extends PhabricatorEventListener {
|
|||
}
|
||||
}
|
||||
|
||||
private function handleActionsEvent($event) {
|
||||
$person = $event->getValue('object');
|
||||
if (!($person instanceof PhabricatorUser)) {
|
||||
return;
|
||||
private function handleActionsEvent(PhutilEvent $event) {
|
||||
$object = $event->getValue('object');
|
||||
|
||||
$actions = null;
|
||||
if ($object instanceof PhabricatorUser) {
|
||||
$actions = $this->renderUserItems($event);
|
||||
}
|
||||
|
||||
$actions = $event->getValue('actions');
|
||||
$this->addActionMenuItems($event, $actions);
|
||||
}
|
||||
|
||||
$username = phutil_escape_uri($person->getUsername());
|
||||
$href = '/audit/view/author/'.$username.'/';
|
||||
private function renderUserItems(PhutilEvent $event) {
|
||||
if (!$this->canUseApplication($event->getUser())) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$actions[] = id(new PhabricatorActionView())
|
||||
$user = $event->getValue('object');
|
||||
|
||||
$username = phutil_escape_uri($user->getUsername());
|
||||
$view_uri = '/audit/view/author/'.$username.'/';
|
||||
|
||||
return id(new PhabricatorActionView())
|
||||
->setIcon('audit-dark')
|
||||
->setIconSheet(PHUIIconView::SPRITE_APPS)
|
||||
->setName(pht('View Commits'))
|
||||
->setHref($href);
|
||||
|
||||
$event->setValue('actions', $actions);
|
||||
->setHref($view_uri);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -15,23 +15,30 @@ final class ConpherenceActionMenuEventListener
|
|||
}
|
||||
}
|
||||
|
||||
private function handleActionsEvent($event) {
|
||||
$person = $event->getValue('object');
|
||||
if (!($person instanceof PhabricatorUser)) {
|
||||
return;
|
||||
private function handleActionsEvent(PhutilEvent $event) {
|
||||
$object = $event->getValue('object');
|
||||
|
||||
$actions = null;
|
||||
if ($object instanceof PhabricatorUser) {
|
||||
$actions = $this->renderUserItems($event);
|
||||
}
|
||||
|
||||
$href = '/conpherence/new/?participant='.$person->getPHID();
|
||||
$this->addActionMenuItems($event, $actions);
|
||||
}
|
||||
|
||||
$actions = $event->getValue('actions');
|
||||
private function renderUserItems(PhutilEvent $event) {
|
||||
if (!$this->canUseApplication($event->getUser())) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$actions[] = id(new PhabricatorActionView())
|
||||
$user = $event->getValue('object');
|
||||
$href = '/conpherence/new/?participant='.$user->getPHID();
|
||||
|
||||
return id(new PhabricatorActionView())
|
||||
->setIcon('message')
|
||||
->setName(pht('Send Message'))
|
||||
->setWorkflow(true)
|
||||
->setHref($href);
|
||||
|
||||
$event->setValue('actions', $actions);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
<?php
|
||||
|
||||
final class DifferentialActionMenuEventListener
|
||||
extends PhabricatorEventListener {
|
||||
|
||||
public function register() {
|
||||
$this->listen(PhabricatorEventType::TYPE_UI_DIDRENDERACTIONS);
|
||||
}
|
||||
|
||||
public function handleEvent(PhutilEvent $event) {
|
||||
switch ($event->getType()) {
|
||||
case PhabricatorEventType::TYPE_UI_DIDRENDERACTIONS:
|
||||
$this->handleActionsEvent($event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private function handleActionsEvent(PhutilEvent $event) {
|
||||
$object = $event->getValue('object');
|
||||
|
||||
$actions = null;
|
||||
if ($object instanceof PhabricatorUser) {
|
||||
$actions = $this->renderUserItems($event);
|
||||
} else if ($object instanceof ManiphestTask) {
|
||||
$actions = $this->renderTaskItems($event);
|
||||
}
|
||||
|
||||
$this->addActionMenuItems($event, $actions);
|
||||
}
|
||||
|
||||
private function renderUserItems(PhutilEvent $event) {
|
||||
if (!$this->canUseApplication($event->getUser())) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$person = $event->getValue('object');
|
||||
$href = '/differential/?authorPHIDs[]='.$person->getPHID();
|
||||
|
||||
return id(new PhabricatorActionView())
|
||||
->setRenderAsForm(true)
|
||||
->setIcon('differential-dark')
|
||||
->setIconSheet(PHUIIconView::SPRITE_APPS)
|
||||
->setName(pht('View Revisions'))
|
||||
->setHref($href);
|
||||
}
|
||||
|
||||
private function renderTaskItems(PhutilEvent $event) {
|
||||
if (!$this->canUseApplication($event->getUser())) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$task = $event->getValue('object');
|
||||
$phid = $task->getPHID();
|
||||
|
||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||
$event->getUser(),
|
||||
$task,
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
|
||||
return id(new PhabricatorActionView())
|
||||
->setName(pht('Edit Differential Revisions'))
|
||||
->setHref("/search/attach/{$phid}/DREV/")
|
||||
->setWorkflow(true)
|
||||
->setIcon('attach')
|
||||
->setDisabled(!$can_edit)
|
||||
->setWorkflow(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class DifferentialActionMenuEventListener
|
||||
extends PhabricatorEventListener {
|
||||
|
||||
public function register() {
|
||||
$this->listen(PhabricatorEventType::TYPE_UI_DIDRENDERACTIONS);
|
||||
}
|
||||
|
||||
public function handleEvent(PhutilEvent $event) {
|
||||
switch ($event->getType()) {
|
||||
case PhabricatorEventType::TYPE_UI_DIDRENDERACTIONS:
|
||||
$this->handleActionsEvent($event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private function handleActionsEvent($event) {
|
||||
$person = $event->getValue('object');
|
||||
if (!($person instanceof PhabricatorUser)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$href = '/differential/?authorPHIDs[]='.$person->getPHID();
|
||||
|
||||
$actions = $event->getValue('actions');
|
||||
|
||||
$actions[] = id(new PhabricatorActionView())
|
||||
->setRenderAsForm(true)
|
||||
->setIcon('differential-dark')
|
||||
->setIconSheet(PHUIIconView::SPRITE_APPS)
|
||||
->setName(pht('View Revisions'))
|
||||
->setHref($href);
|
||||
|
||||
$event->setValue('actions', $actions);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -31,6 +31,10 @@ final class PhabricatorFlagsUIEventListener extends PhabricatorEventListener {
|
|||
return;
|
||||
}
|
||||
|
||||
if (!$this->canUseApplication($event->getUser())) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$flag = PhabricatorFlagQuery::loadUserFlag($user, $object->getPHID());
|
||||
|
||||
if ($flag) {
|
||||
|
|
|
@ -500,28 +500,6 @@ final class ManiphestTaskDetailController extends ManiphestController {
|
|||
->setDisabled(!$can_edit)
|
||||
->setWorkflow(true));
|
||||
|
||||
$view->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setName(pht('Edit Differential Revisions'))
|
||||
->setHref("/search/attach/{$phid}/DREV/")
|
||||
->setWorkflow(true)
|
||||
->setIcon('attach')
|
||||
->setDisabled(!$can_edit)
|
||||
->setWorkflow(true));
|
||||
|
||||
$pholio_app =
|
||||
PhabricatorApplication::getByClass('PhabricatorApplicationPholio');
|
||||
if ($pholio_app->isInstalled()) {
|
||||
$view->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setName(pht('Edit Pholio Mocks'))
|
||||
->setHref("/search/attach/{$phid}/MOCK/edge/")
|
||||
->setWorkflow(true)
|
||||
->setIcon('attach')
|
||||
->setDisabled(!$can_edit)
|
||||
->setWorkflow(true));
|
||||
}
|
||||
|
||||
return $view;
|
||||
}
|
||||
|
||||
|
|
|
@ -14,29 +14,58 @@ final class ManiphestActionMenuEventListener extends PhabricatorEventListener {
|
|||
}
|
||||
}
|
||||
|
||||
private function handleActionsEvent($event) {
|
||||
$actions = $event->getValue('actions');
|
||||
|
||||
$action = id(new PhabricatorActionView())
|
||||
->setIcon('maniphest-dark')
|
||||
->setIconSheet(PHUIIconView::SPRITE_APPS)
|
||||
->setName(pht('View Tasks'));
|
||||
|
||||
private function handleActionsEvent(PhutilEvent $event) {
|
||||
$object = $event->getValue('object');
|
||||
if ($object instanceof PhabricatorUser) {
|
||||
$href = '/maniphest/?statuses[]=0&assigned='.$object->getPHID().'#R';
|
||||
$actions[] = $action->setHref($href);
|
||||
} else if ($object instanceof PhabricatorProject) {
|
||||
$href = '/maniphest/?statuses[]=0&allProjects[]='.$object->getPHID().'#R';
|
||||
$actions[] = $action->setHref($href);
|
||||
|
||||
$actions[] = id(new PhabricatorActionView())
|
||||
->setName(pht("Add Task"))
|
||||
->setIcon('create')
|
||||
->setHref('/maniphest/task/create/?projects=' . $object->getPHID());
|
||||
$actions = null;
|
||||
if ($object instanceof PhabricatorUser) {
|
||||
$actions = $this->renderUserItems($event);
|
||||
} else if ($object instanceof PhabricatorProject) {
|
||||
$actions = $this->renderProjectItems($event);
|
||||
}
|
||||
|
||||
$event->setValue('actions', $actions);
|
||||
$this->addActionMenuItems($event, $actions);
|
||||
}
|
||||
|
||||
private function renderUserItems(PhutilEvent $event) {
|
||||
if (!$this->canUseApplication($event->getUser())) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$user = $event->getValue('object');
|
||||
$phid = $user->getPHID();
|
||||
$view_uri = '/maniphest/?statuses[]=0&assigned='.$phid.'#R';
|
||||
|
||||
return id(new PhabricatorActionView())
|
||||
->setIcon('maniphest-dark')
|
||||
->setIconSheet(PHUIIconView::SPRITE_APPS)
|
||||
->setName(pht('View Tasks'))
|
||||
->setHref($view_uri);
|
||||
}
|
||||
|
||||
private function renderProjectItems(PhutilEvent $event) {
|
||||
if (!$this->canUseApplication($event->getUser())) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$project = $event->getValue('object');
|
||||
|
||||
$phid = $project->getPHID();
|
||||
$view_uri = '/maniphest/?statuses[]=0&allProjects[]='.$phid.'#R';
|
||||
$create_uri = '/maniphest/task/create/?projects='.$phid;
|
||||
|
||||
return array(
|
||||
id(new PhabricatorActionView())
|
||||
->setIcon('maniphest-dark')
|
||||
->setIconSheet(PHUIIconView::SPRITE_APPS)
|
||||
->setName(pht('View Tasks'))
|
||||
->setHref($view_uri),
|
||||
id(new PhabricatorActionView())
|
||||
->setName(pht("Add Task"))
|
||||
->setIcon('create')
|
||||
->setHref($create_uri),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -34,6 +34,12 @@ final class PhabricatorApplicationPholio extends PhabricatorApplication {
|
|||
return true;
|
||||
}
|
||||
|
||||
public function getEventListeners() {
|
||||
return array(
|
||||
new PholioActionMenuEventListener(),
|
||||
);
|
||||
}
|
||||
|
||||
public function getRemarkupRules() {
|
||||
return array(
|
||||
new PholioRemarkupRule(),
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
<?php
|
||||
|
||||
final class PholioActionMenuEventListener
|
||||
extends PhabricatorEventListener {
|
||||
|
||||
public function register() {
|
||||
$this->listen(PhabricatorEventType::TYPE_UI_DIDRENDERACTIONS);
|
||||
}
|
||||
|
||||
public function handleEvent(PhutilEvent $event) {
|
||||
switch ($event->getType()) {
|
||||
case PhabricatorEventType::TYPE_UI_DIDRENDERACTIONS:
|
||||
$this->handleActionsEvent($event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private function handleActionsEvent(PhutilEvent $event) {
|
||||
$object = $event->getValue('object');
|
||||
|
||||
$actions = null;
|
||||
if ($object instanceof ManiphestTask) {
|
||||
$actions = $this->renderTaskItems($event);
|
||||
}
|
||||
|
||||
$this->addActionMenuItems($event, $actions);
|
||||
}
|
||||
|
||||
private function renderTaskItems(PhutilEvent $event) {
|
||||
if (!$this->canUseApplication($event->getUser())) {
|
||||
return;
|
||||
}
|
||||
|
||||
$task = $event->getValue('object');
|
||||
$phid = $task->getPHID();
|
||||
|
||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||
$event->getUser(),
|
||||
$task,
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
|
||||
return id(new PhabricatorActionView())
|
||||
->setName(pht('Edit Pholio Mocks'))
|
||||
->setHref("/search/attach/{$phid}/MOCK/edge/")
|
||||
->setWorkflow(true)
|
||||
->setIcon('attach')
|
||||
->setDisabled(!$can_edit)
|
||||
->setWorkflow(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -33,6 +33,10 @@ final class PhrequentUIEventListener
|
|||
return;
|
||||
}
|
||||
|
||||
if (!$this->canUseApplication($event->getUser())) {
|
||||
return;
|
||||
}
|
||||
|
||||
$tracking = PhrequentUserTimeQuery::isUserTrackingObject(
|
||||
$user,
|
||||
$object->getPHID());
|
||||
|
@ -56,9 +60,7 @@ final class PhrequentUIEventListener
|
|||
$track_action->setDisabled(true);
|
||||
}
|
||||
|
||||
$actions = $event->getValue('actions');
|
||||
$actions[] = $track_action;
|
||||
$event->setValue('actions', $actions);
|
||||
$this->addActionMenuItems($event, $track_action);
|
||||
}
|
||||
|
||||
private function handlePropertyEvent($ui_event) {
|
||||
|
@ -75,6 +77,10 @@ final class PhrequentUIEventListener
|
|||
return;
|
||||
}
|
||||
|
||||
if (!$this->canUseApplication($ui_event->getUser())) {
|
||||
return;
|
||||
}
|
||||
|
||||
$events = id(new PhrequentUserTimeQuery())
|
||||
->setViewer($user)
|
||||
->withObjectPHIDs(array($object->getPHID()))
|
||||
|
|
|
@ -14,22 +14,31 @@ final class PhrictionActionMenuEventListener extends PhabricatorEventListener {
|
|||
}
|
||||
}
|
||||
|
||||
private function handleActionsEvent($event) {
|
||||
$actions = $event->getValue('actions');
|
||||
|
||||
$action = id(new PhabricatorActionView())
|
||||
->setIcon('phriction-dark')
|
||||
->setIconSheet(PHUIIconView::SPRITE_APPS)
|
||||
->setName(pht('View Wiki'));
|
||||
|
||||
private function handleActionsEvent(PhutilEvent $event) {
|
||||
$object = $event->getValue('object');
|
||||
|
||||
$actions = null;
|
||||
if ($object instanceof PhabricatorProject) {
|
||||
$slug = PhabricatorSlug::normalize($object->getPhrictionSlug());
|
||||
$href = '/w/projects/'.$slug;
|
||||
$actions[] = $action->setHref($href);
|
||||
$actions = $this->buildProjectActions($event);
|
||||
}
|
||||
|
||||
$event->setValue('actions', $actions);
|
||||
$this->addActionMenuItems($event, $actions);
|
||||
}
|
||||
|
||||
private function buildProjectActions(PhutilEvent $event) {
|
||||
if (!$this->canUseApplication($event->getUser())) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$project = $event->getValue('object');
|
||||
$slug = PhabricatorSlug::normalize($project->getPhrictionSlug());
|
||||
$href = '/w/projects/'.$slug;
|
||||
|
||||
return id(new PhabricatorActionView())
|
||||
->setIcon('phriction-dark')
|
||||
->setIconSheet(PHUIIconView::SPRITE_APPS)
|
||||
->setName(pht('View Wiki'))
|
||||
->setHref($href);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -33,6 +33,10 @@ final class PhabricatorTokenUIEventListener
|
|||
return;
|
||||
}
|
||||
|
||||
if (!$this->canUseApplication($event->getUser())) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$current = id(new PhabricatorTokenGivenQuery())
|
||||
->setViewer($user)
|
||||
->withAuthorPHIDs(array($user->getPHID()))
|
||||
|
@ -75,6 +79,10 @@ final class PhabricatorTokenUIEventListener
|
|||
return;
|
||||
}
|
||||
|
||||
if (!$this->canUseApplication($event->getUser())) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$limit = 1;
|
||||
|
||||
$tokens_given = id(new PhabricatorTokenGivenQuery())
|
||||
|
|
|
@ -28,6 +28,26 @@ abstract class PhabricatorEventListener extends PhutilEventListener {
|
|||
PhabricatorPolicyCapability::CAN_VIEW);
|
||||
}
|
||||
|
||||
protected function addActionMenuItems(PhutilEvent $event, $items) {
|
||||
if ($event->getType() !== PhabricatorEventType::TYPE_UI_DIDRENDERACTIONS) {
|
||||
throw new Exception("Not an action menu event!");
|
||||
}
|
||||
|
||||
if (!$items) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!is_array($items)) {
|
||||
$items = array($items);
|
||||
}
|
||||
|
||||
$event_actions = $event->getValue('actions');
|
||||
foreach ($items as $item) {
|
||||
$event_actions[] = $item;
|
||||
}
|
||||
$event->setValue('actions', $event_actions);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -42,7 +42,6 @@ final class PhabricatorActionListView extends AphrontView {
|
|||
PhutilEventEngine::dispatchEvent($event);
|
||||
|
||||
$actions = $event->getValue('actions');
|
||||
|
||||
if (!$actions) {
|
||||
return null;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue