Page MenuHomePhabricator

Restrict editing task priority to Trusted-Contributors/staff/etc
Closed, DeclinedPublic

Description

cf. T133541: [RFC] Limit option (or provide alternative) to change the priority of tickets to project members or T819: Restricting modification of tasks when they enter sprints (both not exactly the same but closely related).

Folks changing a task's Priority value (often without bad intentions but "the field was visible so I thought I can") regularly comes up as an issue faced by teams whose workflows rely on the Priority field.

Upstream Phorge (Phabricator) code itself has no further differentiation in the Maniphest (=tasks) application settings: The default Maniphest Edit Policy covers all fields of a task - Priority field and any other fields.
To some extent this was mitigated by the introduction of forms allowing to disable or hide specific UI fields, which however still does not solve the situation as a (Create or Edit) form configuration cannot be bound to a specific user group - it's all users or no users affected by the form configuration, once a task has been created via a form.

I was quite reluctant in the past to restrict editing the Priority field. After having seen vandalism (though that's only weakly related here) and repeated tension over the years I've started to consider this an option.
It would slightly reduce UI complexity for Phab newcomers not aware of its social conventions.
It would reduce workflow collisions, see e.g. https://phabricator.wikimedia.org/T14396#9680109 or https://phabricator.wikimedia.org/T362986#9730145 or https://phabricator.wikimedia.org/T365323 or https://phabricator.wikimedia.org/T365315#9811246 or https://phabricator.wikimedia.org/T368610#9937309 or https://phabricator.wikimedia.org/T366129#9958586 or https://phabricator.wikimedia.org/T49177#9899967 (random latest examples).

Details

Related Changes in GitLab:
TitleReferenceAuthorSource BranchDest Branch
Revert "Expose the Edit Task Priority dropdown field only to trusted users"repos/phabricator/phabricator!84aklapperT363337revertwmf/stable
Expose the Edit Task Priority dropdown field only to trusted usersrepos/phabricator/phabricator!50aklapperT363337editPrioHidewmf/stable
Customize query in GitLab

Event Timeline

Aklapper triaged this task as Medium priority.

Proof of concept:

1diff --git a/src/applications/maniphest/editor/ManiphestEditEngine.php b/src/applications/maniphest/editor/ManiphestEditEngine.php
2index 46877168e7..ed83650e1b 100644
3--- a/src/applications/maniphest/editor/ManiphestEditEngine.php
4+++ b/src/applications/maniphest/editor/ManiphestEditEngine.php
5@@ -145,6 +145,38 @@ EODOCS
6
7 $column_map = $this->getColumnMap($object);
8
9+// WMF BEGIN: Only show Edit Priority when user is member of a trusted project
10+ $can_edit_priority = false;
11+ $viewer = $this->getViewer();
12+ $viewer_phid = $viewer->getPHID();
13+
14+ // ["Trusted-Contributors", "WMF-NDA", "acl*sre-team", "acl*security"];
15+ $trusted_project_phids =
16+ ['PHID-PROJ-rte2hubdntrhiwyoau6n', 'PHID-PROJ-ibxm3v6ithf3jpqpqhl7',
17+ 'PHID-PROJ-fqb3bhereyljcqrsbju7', 'PHID-PROJ-koo4qqdng27q7r65x3cw'];
18+ // PhabricatorProjectQuery does not seem to `&&` for withPHIDs and
19+ // withMemberPHIDs for a nice shortcut, so loop on `isUserMember()` later
20+ $trusted_projects = id(new PhabricatorProjectQuery())
21+ ->setViewer($viewer)
22+ ->withPHIDs($trusted_project_phids)
23+ ->execute();
24+ if (count($trusted_projects) !== 4) {
25+ phlog('WMF Error: Not all projects for checking Edit Priority ' .
26+ 'rights exist. Please correct the PHIDs in the code.');
27+ }
28+ if ($trusted_projects) {
29+ foreach ($trusted_projects as $proj) {
30+ if ($proj instanceof PhabricatorProject &&
31+ $proj->isUserMember($viewer_phid)) {
32+ $can_edit_priority = true;
33+ break;
34+ }
35+ }
36+ } else { // allow to edit priority if no $trusted_projects found AT ALL
37+ $can_edit_priority = true;
38+ }
39+// WMF END: Only show Edit Priority when user is member of a trusted project
40+
41 $fields = array(
42 id(new PhabricatorHandlesEditField())
43 ->setKey('parent')
44@@ -225,6 +257,7 @@ EODOCS
45 ->setIsCopyable(true)
46 ->setValue($object->getPriorityKeyword())
47 ->setOptions($priority_map)
48+ ->setIsHidden(!$can_edit_priority)
49 ->setOptionAliases($alias_map)
50 ->setCommentActionLabel(pht('Change Priority')),
51 );

(A "proper" implementation would span across at least 4 or 5 source code files and I don't consider this request acceptable by upstream, so I prefer to keep custom downstream changes quite local. Details for myself: Properly implementing a Capacity would require expanding ManiphestTask.php to have a setPriorityEditPolicy() method, expand getCustomCapabilities() in PhabricatorManiphestApplication.php, introduce a class ManiphestDefaultPriorityEditCapability.php, etc etc).

Pppery rescinded a token.
Pppery awarded a token.

Notes to myself:

  • Tested task creation as average user. Works as expected: Priority field not shown in the UI and task successfully created wth default priority.
  • This code change does not affect bulk editing: The "Set Priority" option is still available as a bulk action even though the performing user is not a member of one of the four projects. That's fine IMO as bulk edits are limited to acl*Batch-Editors members anyway.

Would this mean that people like me couldn’t put Unbreak Now! priority to the tasks that require it?

It would mean that only members of Trusted-Contributors, WMF-NDA acl*sre-team or acl*security can change the Priority field value.

It would mean that only members of Trusted-Contributors, WMF-NDA acl*sre-team or acl*security can change the Priority field value.

I hope this would mean that addition to Trusted-Contributors would be more active then because this would effectively hinder ability of many less active Phabricator contributors to report the urgent tasks (I was added to the group but I assume many others, even admins from different wikis, will be forgotten).

It would mean that only members of Trusted-Contributors, WMF-NDA acl*sre-team or acl*security can change the Priority field value.

my guess is onboarding varies a bit so we make sure wmf+affiliate staff are all in at least one of those groups.

To make this change in behavior less disruptive for PMs etc, should check first which non-deactivated Phab user accounts have been active setting the Priority field in the last six months and are neither in Trusted-Contributors nor WMF-NDA, and add them:
SELECT usr.username, COUNT(usr.username) AS cnt FROM phabricator_maniphest.maniphest_transaction trs JOIN phabricator_user.user usr WHERE trs.transactionType = "priority" AND FROM_UNIXTIME(trs.dateModified) >= (NOW() - INTERVAL 6 MONTH) AND trs.authorPHID = usr.phid AND usr.isDisabled != 1 AND usr.phid NOT IN (SELECT e.src FROM phabricator_user.edge e WHERE e.dst = "PHID-PROJ-rte2hubdntrhiwyoau6n" AND e.type = 14) AND usr.phid NOT IN (SELECT e.src FROM phabricator_user.edge e WHERE e.dst = "PHID-PROJ-ibxm3v6ithf3jpqpqhl7" AND e.type = 14) GROUP BY usr.username ORDER BY cnt DESC LIMIT 80;

To make this change in behavior less disruptive for PMs etc, should check first which non-deactivated Phab user accounts have been active setting the Priority field in the last six months and are neither in Trusted-Contributors nor WMF-NDA, and add them:

Was this done? And is there any plan to add active members of Phabricator community to Trusted-Contributors more quickly after this change got merged?

Was this done?

Yes.

And is there any plan to add active members of Phabricator community to Trusted-Contributors more quickly after this change got merged?

No (as I cannot predict how quick nearly 800 people will do things in the future). :)

as I cannot predict how quick nearly 800 people will do things in the future :)

I mean, you spearheaded this effort to tie an important permission to the group. I think there should be some (organisational) responsibility on your part to give the permissions out to people who are definitely trusted enough after this change got merged (IAdmins or admins on Wikimedia wikis, for instance). At least one of the members of the new Product and Technology Advisory Council wasn’t in that group until I added them yesterday, I wasn’t until I mentioned it in this very task, and how many others are like that?

to give the permissions out to people who are definitely trusted enough after this change got merged

I did for those who have already been active setting priorities in T363337#10124562. I cannot foresee the future though. :)

IAdmins or admins on Wikimedia wikis, for instance

I don't plan to collect data from all 900 wikis and sync it against Phabricator accounts.
If you or others know and trust folks who should have priority setting permissions, feel free to add them to Trusted-Contributors, just like before.

until I added them yesterday

Thanks for doing that!

how many others are like that?

If you have an idea how to find out, please share it. Thanks!

Basically: If you think you need permissions, ask for permissions. That's a common concept in Wikimedia (and Phabricator, for example to create projects, mass-edit tasks, create forms, etc etc). I don't plan to invert the concept by starting to actively search for folks who should have permissions in this very case. Sure, for a few folks this change might be initially disruptive but that's the thing with changes - we had the same situation when we introduced Trusted-Contributors ("why can't I not do xyz in Phab anymore?"), it's hard to always identify everyone who may benefit from being included in those additional permissions.

Aklapper renamed this task from Explore restricting editing task priority to Trusted-Contributors/staff/etc to Restrict editing task priority to Trusted-Contributors/staff/etc.Oct 22 2024, 2:54 PM

My patch merged on 2024-10-22 never worked as expected, for reasons I still cannot figure out.
I'll try again with https://gitlab.wikimedia.org/repos/phabricator/phabricator/-/commit/4b00a968e116d235b6c9f7c73916d758f5293e9f which seems to work.

aklapper merged https://gitlab.wikimedia.org/repos/phabricator/phabricator/-/merge_requests/84

Revert "Expose the Edit Task Priority dropdown field only to trusted users"

Setting this restriction for the default form worked correctly with the patch which I reverted half an hour ago but afterwards that overwritten visibility/lock setting of the Priority field gets overwritten by whatever is defined for the Priority field by the used non-default EditEngine form.
And by default, there is only locking on the level of the entire form, not for particular fields of the form.

The right place to interfere would be when loading a form config in PhabricatorEditEngineConfiguration.
But that class has no way to get the current actor (to check the actor's project memberships etc).

Thus I'm declining this idea for now.

Pasting the latest code I played with, in case someone ever wants to pick this up again:

[acko@fedora phabricator (wmf/stable *$|u=)]$ git diff src/applications/transactions/storage/PhabricatorEditEngineConfiguration.php
diff --git a/src/applications/transactions/storage/PhabricatorEditEngineConfiguration.php b/src/applications/transactions/storage/PhabricatorEditEngineConfiguration.php
index e3448c676b..e3f1a41c61 100644
--- a/src/applications/transactions/storage/PhabricatorEditEngineConfiguration.php
+++ b/src/applications/transactions/storage/PhabricatorEditEngineConfiguration.php
@@ -18,6 +18,8 @@ final class PhabricatorEditEngineConfiguration
   protected $editOrder = 0;
   protected $subtype;
 
+  private $actor; // WMF T363337
+
   private $engine = self::ATTACHABLE;
 
   const LOCK_VISIBLE = 'visible';
@@ -32,6 +34,7 @@ final class PhabricatorEditEngineConfiguration
     PhabricatorUser $actor,
     PhabricatorEditEngine $engine) {
 
+    $this->$actor = $actor; // WMF T363337; no other way to get actor. But does not work because static function.
     return id(new PhabricatorEditEngineConfiguration())
       ->setSubtype(PhabricatorEditEngine::SUBTYPE_DEFAULT)
       ->setEngineKey($engine->getEngineKey())
@@ -175,6 +178,23 @@ final class PhabricatorEditEngineConfiguration
           if ($field->getIsLockable()) {
             $field->setIsLocked(false);
           }
+          // WMF hack BEGIN: Only show Edit Priority when user is trusted - T363337
+          if ($key == 'priority') {
+            $actor_phid = $this->$actor->getPHID();
+            $trusted_project_names = ["Trusted-Contributors", "WMF-NDA", "acl*sre-team",
+                                      "acl*security", "acl*Batch-Editors", "acl*phabricator"];
+            $projects = WMFSecurityPolicy::getProjectByName($trusted_project_names, $actor_phid, true);
+            if ($projects) { // allow to edit priority if no $projects found AT ALL
+              foreach ($projects as $proj) {
+                if ($proj instanceof PhabricatorProject && $proj->isUserMember($actor_phid)) {
+                  break;
+                }
+              }
+            } else {
+              $field->setIsLocked(true);
+            }
+          }
+          // WMF hack END: Only show Edit Priority when user is trusted - T363337
           break;
         default:
           // If we don't have an explicit value, hide the field. This way,