Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F15400055
D7357.id16564.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
22 KB
Referenced Files
None
Subscribers
None
D7357.id16564.diff
View Options
Index: src/__phutil_library_map__.php
===================================================================
--- src/__phutil_library_map__.php
+++ src/__phutil_library_map__.php
@@ -706,8 +706,14 @@
'LiskRawMigrationIterator' => 'infrastructure/storage/lisk/LiskRawMigrationIterator.php',
'ManiphestAction' => 'applications/maniphest/constants/ManiphestAction.php',
'ManiphestBatchEditController' => 'applications/maniphest/controller/ManiphestBatchEditController.php',
+ 'ManiphestCapabilityBulkEdit' => 'applications/maniphest/capability/ManiphestCapabilityBulkEdit.php',
'ManiphestCapabilityDefaultEdit' => 'applications/maniphest/capability/ManiphestCapabilityDefaultEdit.php',
'ManiphestCapabilityDefaultView' => 'applications/maniphest/capability/ManiphestCapabilityDefaultView.php',
+ 'ManiphestCapabilityEditAssign' => 'applications/maniphest/capability/ManiphestCapabilityEditAssign.php',
+ 'ManiphestCapabilityEditPolicies' => 'applications/maniphest/capability/ManiphestCapabilityEditPolicies.php',
+ 'ManiphestCapabilityEditPriority' => 'applications/maniphest/capability/ManiphestCapabilityEditPriority.php',
+ 'ManiphestCapabilityEditProjects' => 'applications/maniphest/capability/ManiphestCapabilityEditProjects.php',
+ 'ManiphestCapabilityEditStatus' => 'applications/maniphest/capability/ManiphestCapabilityEditStatus.php',
'ManiphestConfiguredCustomField' => 'applications/maniphest/field/ManiphestConfiguredCustomField.php',
'ManiphestConstants' => 'applications/maniphest/constants/ManiphestConstants.php',
'ManiphestController' => 'applications/maniphest/controller/ManiphestController.php',
@@ -2844,8 +2850,14 @@
'LiskRawMigrationIterator' => 'PhutilBufferedIterator',
'ManiphestAction' => 'ManiphestConstants',
'ManiphestBatchEditController' => 'ManiphestController',
+ 'ManiphestCapabilityBulkEdit' => 'PhabricatorPolicyCapability',
'ManiphestCapabilityDefaultEdit' => 'PhabricatorPolicyCapability',
'ManiphestCapabilityDefaultView' => 'PhabricatorPolicyCapability',
+ 'ManiphestCapabilityEditAssign' => 'PhabricatorPolicyCapability',
+ 'ManiphestCapabilityEditPolicies' => 'PhabricatorPolicyCapability',
+ 'ManiphestCapabilityEditPriority' => 'PhabricatorPolicyCapability',
+ 'ManiphestCapabilityEditProjects' => 'PhabricatorPolicyCapability',
+ 'ManiphestCapabilityEditStatus' => 'PhabricatorPolicyCapability',
'ManiphestConfiguredCustomField' =>
array(
0 => 'ManiphestCustomField',
Index: src/applications/maniphest/application/PhabricatorApplicationManiphest.php
===================================================================
--- src/applications/maniphest/application/PhabricatorApplicationManiphest.php
+++ src/applications/maniphest/application/PhabricatorApplicationManiphest.php
@@ -67,7 +67,7 @@
'export/(?P<key>[^/]+)/' => 'ManiphestExportController',
'subpriority/' => 'ManiphestSubpriorityController',
'subscribe/(?P<action>add|rem)/(?P<id>[1-9]\d*)/'
- => 'ManiphestSubscribeController',
+ => 'ManiphestSubscribeController',
),
);
}
@@ -100,6 +100,18 @@
'caption' => pht(
'Default edit policy for newly created tasks.'),
),
+ ManiphestCapabilityEditStatus::CAPABILITY => array(
+ ),
+ ManiphestCapabilityEditAssign::CAPABILITY => array(
+ ),
+ ManiphestCapabilityEditPolicies::CAPABILITY => array(
+ ),
+ ManiphestCapabilityEditPriority::CAPABILITY => array(
+ ),
+ ManiphestCapabilityEditProjects::CAPABILITY => array(
+ ),
+ ManiphestCapabilityBulkEdit::CAPABILITY => array(
+ ),
);
}
Index: src/applications/maniphest/capability/ManiphestCapabilityBulkEdit.php
===================================================================
--- /dev/null
+++ src/applications/maniphest/capability/ManiphestCapabilityBulkEdit.php
@@ -0,0 +1,20 @@
+<?php
+
+final class ManiphestCapabilityBulkEdit
+ extends PhabricatorPolicyCapability {
+
+ const CAPABILITY = 'maniphest.edit.bulk';
+
+ public function getCapabilityKey() {
+ return self::CAPABILITY;
+ }
+
+ public function getCapabilityName() {
+ return pht('Can Bulk Edit Tasks');
+ }
+
+ public function describeCapabilityRejection() {
+ return pht('You do not have permission to bulk edit tasks.');
+ }
+
+}
Index: src/applications/maniphest/capability/ManiphestCapabilityEditAssign.php
===================================================================
--- /dev/null
+++ src/applications/maniphest/capability/ManiphestCapabilityEditAssign.php
@@ -0,0 +1,20 @@
+<?php
+
+final class ManiphestCapabilityEditAssign
+ extends PhabricatorPolicyCapability {
+
+ const CAPABILITY = 'maniphest.edit.assign';
+
+ public function getCapabilityKey() {
+ return self::CAPABILITY;
+ }
+
+ public function getCapabilityName() {
+ return pht('Can Assign Tasks');
+ }
+
+ public function describeCapabilityRejection() {
+ return pht('You do not have permission to assign tasks.');
+ }
+
+}
Index: src/applications/maniphest/capability/ManiphestCapabilityEditPolicies.php
===================================================================
--- /dev/null
+++ src/applications/maniphest/capability/ManiphestCapabilityEditPolicies.php
@@ -0,0 +1,20 @@
+<?php
+
+final class ManiphestCapabilityEditPolicies
+ extends PhabricatorPolicyCapability {
+
+ const CAPABILITY = 'maniphest.edit.policies';
+
+ public function getCapabilityKey() {
+ return self::CAPABILITY;
+ }
+
+ public function getCapabilityName() {
+ return pht('Can Edit Task Policies');
+ }
+
+ public function describeCapabilityRejection() {
+ return pht('You do not have permission to edit task policies.');
+ }
+
+}
Index: src/applications/maniphest/capability/ManiphestCapabilityEditPriority.php
===================================================================
--- /dev/null
+++ src/applications/maniphest/capability/ManiphestCapabilityEditPriority.php
@@ -0,0 +1,20 @@
+<?php
+
+final class ManiphestCapabilityEditPriority
+ extends PhabricatorPolicyCapability {
+
+ const CAPABILITY = 'maniphest.edit.priority';
+
+ public function getCapabilityKey() {
+ return self::CAPABILITY;
+ }
+
+ public function getCapabilityName() {
+ return pht('Can Prioritize Tasks');
+ }
+
+ public function describeCapabilityRejection() {
+ return pht('You do not have permission to prioritize tasks.');
+ }
+
+}
Index: src/applications/maniphest/capability/ManiphestCapabilityEditProjects.php
===================================================================
--- /dev/null
+++ src/applications/maniphest/capability/ManiphestCapabilityEditProjects.php
@@ -0,0 +1,20 @@
+<?php
+
+final class ManiphestCapabilityEditProjects
+ extends PhabricatorPolicyCapability {
+
+ const CAPABILITY = 'maniphest.edit.projects';
+
+ public function getCapabilityKey() {
+ return self::CAPABILITY;
+ }
+
+ public function getCapabilityName() {
+ return pht('Can Edit Task Projects');
+ }
+
+ public function describeCapabilityRejection() {
+ return pht('You do not have permission to edit task projects.');
+ }
+
+}
Index: src/applications/maniphest/capability/ManiphestCapabilityEditStatus.php
===================================================================
--- /dev/null
+++ src/applications/maniphest/capability/ManiphestCapabilityEditStatus.php
@@ -0,0 +1,20 @@
+<?php
+
+final class ManiphestCapabilityEditStatus
+ extends PhabricatorPolicyCapability {
+
+ const CAPABILITY = 'maniphest.edit.status';
+
+ public function getCapabilityKey() {
+ return self::CAPABILITY;
+ }
+
+ public function getCapabilityName() {
+ return pht('Can Edit Task Status');
+ }
+
+ public function describeCapabilityRejection() {
+ return pht('You do not have permission to edit task status.');
+ }
+
+}
Index: src/applications/maniphest/controller/ManiphestBatchEditController.php
===================================================================
--- src/applications/maniphest/controller/ManiphestBatchEditController.php
+++ src/applications/maniphest/controller/ManiphestBatchEditController.php
@@ -7,6 +7,9 @@
public function processRequest() {
+ $this->requireApplicationCapability(
+ ManiphestCapabilityBulkEdit::CAPABILITY);
+
$request = $this->getRequest();
$user = $request->getUser();
Index: src/applications/maniphest/controller/ManiphestTaskDetailController.php
===================================================================
--- src/applications/maniphest/controller/ManiphestTaskDetailController.php
+++ src/applications/maniphest/controller/ManiphestTaskDetailController.php
@@ -165,6 +165,27 @@
ManiphestTransaction::TYPE_PROJECTS => pht('Associate Projects'),
);
+ // Remove actions the user doesn't have permission to take.
+
+ $requires = array(
+ ManiphestTransaction::TYPE_OWNER =>
+ ManiphestCapabilityEditAssign::CAPABILITY,
+ ManiphestTransaction::TYPE_PRIORITY =>
+ ManiphestCapabilityEditPriority::CAPABILITY,
+ ManiphestTransaction::TYPE_PROJECTS =>
+ ManiphestCapabilityEditProjects::CAPABILITY,
+ ManiphestTransaction::TYPE_STATUS =>
+ ManiphestCapabilityEditStatus::CAPABILITY,
+ );
+
+ foreach ($transaction_types as $type => $name) {
+ if (isset($requires[$type])) {
+ if (!$this->hasApplicationCapability($requires[$type])) {
+ unset($transaction_types[$type]);
+ }
+ }
+ }
+
if ($task->getStatus() == ManiphestTaskStatus::STATUS_OPEN) {
$resolution_types = array_select_keys(
$resolution_types,
Index: src/applications/maniphest/controller/ManiphestTaskEditController.php
===================================================================
--- src/applications/maniphest/controller/ManiphestTaskEditController.php
+++ src/applications/maniphest/controller/ManiphestTaskEditController.php
@@ -1,8 +1,5 @@
<?php
-/**
- * @group maniphest
- */
final class ManiphestTaskEditController extends ManiphestController {
private $id;
@@ -16,6 +13,17 @@
$request = $this->getRequest();
$user = $request->getUser();
+ $can_edit_assign = $this->hasApplicationCapability(
+ ManiphestCapabilityEditAssign::CAPABILITY);
+ $can_edit_policies = $this->hasApplicationCapability(
+ ManiphestCapabilityEditPolicies::CAPABILITY);
+ $can_edit_priority = $this->hasApplicationCapability(
+ ManiphestCapabilityEditPriority::CAPABILITY);
+ $can_edit_projects = $this->hasApplicationCapability(
+ ManiphestCapabilityEditProjects::CAPABILITY);
+ $can_edit_status = $this->hasApplicationCapability(
+ ManiphestCapabilityEditStatus::CAPABILITY);
+
$files = array();
$parent_task = null;
$template_id = null;
@@ -40,20 +48,24 @@
if (!$request->isFormPost()) {
$task->setTitle($request->getStr('title'));
- $default_projects = $request->getStr('projects');
- if ($default_projects) {
- $task->setProjectPHIDs(explode(';', $default_projects));
+ if ($can_edit_projects) {
+ $default_projects = $request->getStr('projects');
+ if ($default_projects) {
+ $task->setProjectPHIDs(explode(';', $default_projects));
+ }
}
$task->setDescription($request->getStr('description'));
- $assign = $request->getStr('assign');
- if (strlen($assign)) {
- $assign_user = id(new PhabricatorUser())->loadOneWhere(
- 'username = %s',
- $assign);
- if ($assign_user) {
- $task->setOwnerPHID($assign_user->getPHID());
+ if ($can_edit_assign) {
+ $assign = $request->getStr('assign');
+ if (strlen($assign)) {
+ $assign_user = id(new PhabricatorUser())->loadOneWhere(
+ 'username = %s',
+ $assign);
+ if ($assign_user) {
+ $task->setOwnerPHID($assign_user->getPHID());
+ }
}
}
}
@@ -122,7 +134,9 @@
$changes[ManiphestTransaction::TYPE_TITLE] = $new_title;
$changes[ManiphestTransaction::TYPE_DESCRIPTION] = $new_desc;
- $changes[ManiphestTransaction::TYPE_STATUS] = $new_status;
+ if ($can_edit_status) {
+ $changes[ManiphestTransaction::TYPE_STATUS] = $new_status;
+ }
$owner_tokenizer = $request->getArr('assigned_to');
$owner_phid = reset($owner_tokenizer);
@@ -173,17 +187,27 @@
$task->setProjectPHIDs($request->getArr('projects'));
} else {
- $changes[ManiphestTransaction::TYPE_PRIORITY] =
- $request->getInt('priority');
- $changes[ManiphestTransaction::TYPE_OWNER] = $owner_phid;
+ if ($can_edit_priority) {
+ $changes[ManiphestTransaction::TYPE_PRIORITY] =
+ $request->getInt('priority');
+ }
+ if ($can_edit_assign) {
+ $changes[ManiphestTransaction::TYPE_OWNER] = $owner_phid;
+ }
+
$changes[ManiphestTransaction::TYPE_CCS] = $request->getArr('cc');
- $changes[ManiphestTransaction::TYPE_PROJECTS] =
- $request->getArr('projects');
- $changes[PhabricatorTransactions::TYPE_VIEW_POLICY] =
- $request->getStr('viewPolicy');
- $changes[PhabricatorTransactions::TYPE_EDIT_POLICY] =
- $request->getStr('editPolicy');
+ if ($can_edit_projects) {
+ $changes[ManiphestTransaction::TYPE_PROJECTS] =
+ $request->getArr('projects');
+ }
+
+ if ($can_edit_policies) {
+ $changes[PhabricatorTransactions::TYPE_VIEW_POLICY] =
+ $request->getStr('viewPolicy');
+ $changes[PhabricatorTransactions::TYPE_EDIT_POLICY] =
+ $request->getStr('editPolicy');
+ }
if ($files) {
$file_map = mpull($files, 'getPHID');
@@ -418,7 +442,7 @@
->setHeight(AphrontFormTextAreaControl::HEIGHT_VERY_SHORT)
->setValue($task->getTitle()));
- if ($task->getID()) {
+ if ($task->getID() && $can_edit_status) {
// Only show this in "edit" mode, not "create" mode, since creating a
// non-open task is kind of silly and it would just clutter up the
// "create" interface.
@@ -436,58 +460,73 @@
->setObject($task)
->execute();
- $form
- ->appendChild(
+ if ($can_edit_assign) {
+ $form->appendChild(
id(new AphrontFormTokenizerControl())
->setLabel(pht('Assigned To'))
->setName('assigned_to')
->setValue($assigned_value)
->setUser($user)
->setDatasource('/typeahead/common/users/')
- ->setLimit(1))
+ ->setLimit(1));
+ }
+
+ $form
->appendChild(
id(new AphrontFormTokenizerControl())
->setLabel(pht('CC'))
->setName('cc')
->setValue($cc_value)
->setUser($user)
- ->setDatasource('/typeahead/common/mailable/'))
- ->appendChild(
- id(new AphrontFormSelectControl())
- ->setLabel(pht('Priority'))
- ->setName('priority')
- ->setOptions($priority_map)
- ->setValue($task->getPriority()))
- ->appendChild(
- id(new AphrontFormPolicyControl())
- ->setUser($user)
- ->setCapability(PhabricatorPolicyCapability::CAN_VIEW)
- ->setPolicyObject($task)
- ->setPolicies($policies)
- ->setName('viewPolicy'))
- ->appendChild(
- id(new AphrontFormPolicyControl())
- ->setUser($user)
- ->setCapability(PhabricatorPolicyCapability::CAN_EDIT)
- ->setPolicyObject($task)
- ->setPolicies($policies)
- ->setName('editPolicy'))
- ->appendChild(
- id(new AphrontFormTokenizerControl())
- ->setLabel(pht('Projects'))
- ->setName('projects')
- ->setValue($projects_value)
- ->setID($project_tokenizer_id)
- ->setCaption(
- javelin_tag(
- 'a',
- array(
- 'href' => '/project/create/',
- 'mustcapture' => true,
- 'sigil' => 'project-create',
- ),
- pht('Create New Project')))
- ->setDatasource('/typeahead/common/projects/'));
+ ->setDatasource('/typeahead/common/mailable/'));
+
+ if ($can_edit_priority) {
+ $form
+ ->appendChild(
+ id(new AphrontFormSelectControl())
+ ->setLabel(pht('Priority'))
+ ->setName('priority')
+ ->setOptions($priority_map)
+ ->setValue($task->getPriority()));
+ }
+
+ if ($can_edit_policies) {
+ $form
+ ->appendChild(
+ id(new AphrontFormPolicyControl())
+ ->setUser($user)
+ ->setCapability(PhabricatorPolicyCapability::CAN_VIEW)
+ ->setPolicyObject($task)
+ ->setPolicies($policies)
+ ->setName('viewPolicy'))
+ ->appendChild(
+ id(new AphrontFormPolicyControl())
+ ->setUser($user)
+ ->setCapability(PhabricatorPolicyCapability::CAN_EDIT)
+ ->setPolicyObject($task)
+ ->setPolicies($policies)
+ ->setName('editPolicy'));
+ }
+
+ if ($can_edit_projects) {
+ $form
+ ->appendChild(
+ id(new AphrontFormTokenizerControl())
+ ->setLabel(pht('Projects'))
+ ->setName('projects')
+ ->setValue($projects_value)
+ ->setID($project_tokenizer_id)
+ ->setCaption(
+ javelin_tag(
+ 'a',
+ array(
+ 'href' => '/project/create/',
+ 'mustcapture' => true,
+ 'sigil' => 'project-create',
+ ),
+ pht('Create New Project')))
+ ->setDatasource('/typeahead/common/projects/'));
+ }
foreach ($aux_fields as $aux_field) {
$aux_control = $aux_field->renderEditControl();
Index: src/applications/maniphest/controller/ManiphestTaskListController.php
===================================================================
--- src/applications/maniphest/controller/ManiphestTaskListController.php
+++ src/applications/maniphest/controller/ManiphestTaskListController.php
@@ -46,7 +46,11 @@
$group_parameter,
$handles);
+ $can_edit_priority = $this->hasApplicationCapability(
+ ManiphestCapabilityEditPriority::CAPABILITY);
+
$can_drag = ($order_parameter == 'priority') &&
+ ($can_edit_priority) &&
($group_parameter == 'none' || $group_parameter == 'priority');
if (!$viewer->isLoggedIn()) {
@@ -91,11 +95,13 @@
));
}
- Javelin::initBehavior(
- 'maniphest-subpriority-editor',
- array(
- 'uri' => '/maniphest/subpriority/',
- ));
+ if ($can_drag) {
+ Javelin::initBehavior(
+ 'maniphest-subpriority-editor',
+ array(
+ 'uri' => '/maniphest/subpriority/',
+ ));
+ }
return phutil_tag(
'div',
@@ -191,6 +197,11 @@
private function renderBatchEditor(PhabricatorSavedQuery $saved_query) {
$user = $this->getRequest()->getUser();
+ $batch_capability = ManiphestCapabilityBulkEdit::CAPABILITY;
+ if (!$this->hasApplicationCapability($batch_capability)) {
+ return null;
+ }
+
if (!$user->isLoggedIn()) {
// Don't show the batch editor or excel export for logged-out users.
// Technically we //could// let them export, but ehh.
Index: src/applications/maniphest/editor/ManiphestTransactionEditor.php
===================================================================
--- src/applications/maniphest/editor/ManiphestTransactionEditor.php
+++ src/applications/maniphest/editor/ManiphestTransactionEditor.php
@@ -81,9 +81,9 @@
case ManiphestTransaction::TYPE_EDGE:
return $xaction->getNewValue();
}
-
}
+
protected function transactionHasEffect(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
@@ -249,6 +249,43 @@
}
}
+ protected function requireCapabilities(
+ PhabricatorLiskDAO $object,
+ PhabricatorApplicationTransaction $xaction) {
+
+ parent::requireCapabilities($object, $xaction);
+
+ $app_capability_map = array(
+ ManiphestTransaction::TYPE_PRIORITY =>
+ ManiphestCapabilityEditPriority::CAPABILITY,
+ ManiphestTransaction::TYPE_STATUS =>
+ ManiphestCapabilityEditStatus::CAPABILITY,
+ ManiphestTransaction::TYPE_PROJECTS =>
+ ManiphestCapabilityEditProjects::CAPABILITY,
+ ManiphestTransaction::TYPE_OWNER =>
+ ManiphestCapabilityEditAssign::CAPABILITY,
+ PhabricatorTransactions::TYPE_EDIT_POLICY =>
+ ManiphestCapabilityEditPolicies::CAPABILITY,
+ PhabricatorTransactions::TYPE_VIEW_POLICY =>
+ ManiphestCapabilityEditPolicies::CAPABILITY,
+ );
+
+ $transaction_type = $xaction->getTransactionType();
+ $app_capability = idx($app_capability_map, $transaction_type);
+
+ if ($app_capability) {
+ $app = id(new PhabricatorApplicationQuery())
+ ->setViewer($this->getActor())
+ ->withClasses(array('PhabricatorApplicationManiphest'))
+ ->executeOne();
+ PhabricatorPolicyFilter::requireCapability(
+ $this->getActor(),
+ $app,
+ $app_capability);
+ }
+ }
+
+
public static function getNextSubpriority($pri, $sub) {
// TODO: T603 Figure out what the policies here should be once this gets
Index: src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php
===================================================================
--- src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php
+++ src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php
@@ -460,6 +460,12 @@
return array();
}
+ // Now that we've merged, filtered, and combined transactions, check for
+ // required capabilities.
+ foreach ($xactions as $xaction) {
+ $this->requireCapabilities($object, $xaction);
+ }
+
$xactions = $this->sortTransactions($xactions);
if ($is_preview) {
@@ -696,10 +702,6 @@
$actor,
$object,
PhabricatorPolicyCapability::CAN_VIEW);
-
- foreach ($xactions as $xaction) {
- $this->requireCapabilities($object, $xaction);
- }
}
protected function requireCapabilities(
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Mar 18, 9:23 AM (2 w, 1 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7704735
Default Alt Text
D7357.id16564.diff (22 KB)
Attached To
Mode
D7357: Add capabilities for editing task triage details (priority, assignee, etc)
Attached
Detach File
Event Timeline
Log In to Comment