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

Fix a complicated object caching issue with the policy filter

Summary:
Fixes T11853. To set this up:

- Create "Project A".
- Join "Project A".
- Create a subproject, "Project A Subproject 1".
- This causes Project A to become a parent project.
- This moves you to be a member of "Project A Subproject 1" instead of "Project A" directly.
- Create another subproject, "Project A Subproject 2".
- Do not join this subproject.
- Set the second subproject's policy to "Visible To: Members of Project A".
- Try to edit the second subproject.

Before this change, this fails:

- When querying projects, we sometime try to skip loading the viewer's membership in ancestor projects as a small optimization.
- Via `PhabricatorExtendedPolicyInterface`, we may then return the parent project to the policy filter for extended checks.
- The PolicyFilter has an optimization: if we're checking an object, and we already have that object, we can just use the object we already have. This is common and useful.
- However, in this case it causes us to reuse an incomplete object (an object without proper membership information). We fail a policy check which we should pass.

Instead, don't skip loading the viewer's membership in ancestor projects.

Test Plan:
- Did all that stuff above.
- Could edit the subproject.
- Ran `arc unit --everything`.

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T11853

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

+7 -7
+7 -7
src/applications/project/query/PhabricatorProjectQuery.php
··· 260 260 261 261 $all_graph = $this->getAllReachableAncestors($projects); 262 262 263 - if ($this->needAncestorMembers || $this->needWatchers) { 264 - $src_projects = $all_graph; 265 - } else { 266 - $src_projects = $projects; 267 - } 263 + // NOTE: Although we may not need much information about ancestors, we 264 + // always need to test if the viewer is a member, because we will return 265 + // ancestor projects to the policy filter via ExtendedPolicy calls. If 266 + // we skip populating membership data on a parent, the policy framework 267 + // will think the user is not a member of the parent project. 268 268 269 269 $all_sources = array(); 270 - foreach ($src_projects as $project) { 270 + foreach ($all_graph as $project) { 271 271 // For milestones, we need parent members. 272 272 if ($project->isMilestone()) { 273 273 $parent_phid = $project->getParentProjectPHID(); ··· 306 306 } 307 307 308 308 $membership_projects = array(); 309 - foreach ($src_projects as $project) { 309 + foreach ($all_graph as $project) { 310 310 $project_phid = $project->getPHID(); 311 311 312 312 if ($project->isMilestone()) {