public function testSpacesSeveralSpaces() { $this->destroyAllSpaces(); // Try creating a few spaces, one of which is a default space. This should // work fine. $actor = $this->generateNewTestUser(); $default = $this->newSpace($actor, pht('Default Space'), true); $this->newSpace($actor, pht('Alternate Space'), false); $this->assertEqual(2, count($this->loadAllSpaces())); $this->assertEqual(2, count(PhabricatorSpacesNamespaceQuery::getAllSpaces())); $cache_default = PhabricatorSpacesNamespaceQuery::getDefaultSpace(); $this->assertEqual($default->getPHID(), $cache_default->getPHID()); }
private function canViewerSeeObjectsInSpace(PhabricatorUser $viewer, $space_phid) { $spaces = PhabricatorSpacesNamespaceQuery::getAllSpaces(); // If there are no spaces, everything exists in an implicit default space // with no policy controls. This is the default state. if (!$spaces) { if ($space_phid !== null) { return false; } else { return true; } } if ($space_phid === null) { $space = PhabricatorSpacesNamespaceQuery::getDefaultSpace(); } else { $space = idx($spaces, $space_phid); } if (!$space) { return false; } // This may be more involved later, but for now being able to see the // space is equivalent to being able to see everything in it. return self::hasCapability($viewer, $space, PhabricatorPolicyCapability::CAN_VIEW); }
/** * Constrain the query to include only results in valid Spaces. * * This method builds part of a WHERE clause which considers the spaces the * viewer has access to see with any explicit constraint on spaces added by * @{method:withSpacePHIDs}. * * @param AphrontDatabaseConnection Database connection. * @return string Part of a WHERE clause. * @task spaces */ private function buildSpacesWhereClause(AphrontDatabaseConnection $conn) { $object = $this->newResultObject(); if (!$object) { return null; } if (!$object instanceof PhabricatorSpacesInterface) { return null; } $viewer = $this->getViewer(); // If we have an omnipotent viewer and no formal space constraints, don't // emit a clause. This primarily enables older migrations to run cleanly, // without fataling because they try to match a `spacePHID` column which // does not exist yet. See T8743, T8746. if ($viewer->isOmnipotent()) { if ($this->spaceIsArchived === null && $this->spacePHIDs === null) { return null; } } $space_phids = array(); $include_null = false; $all = PhabricatorSpacesNamespaceQuery::getAllSpaces(); if (!$all) { // If there are no spaces at all, implicitly give the viewer access to // the default space. $include_null = true; } else { // Otherwise, give them access to the spaces they have permission to // see. $viewer_spaces = PhabricatorSpacesNamespaceQuery::getViewerSpaces($viewer); foreach ($viewer_spaces as $viewer_space) { if ($this->spaceIsArchived !== null) { if ($viewer_space->getIsArchived() != $this->spaceIsArchived) { continue; } } $phid = $viewer_space->getPHID(); $space_phids[$phid] = $phid; if ($viewer_space->getIsDefaultNamespace()) { $include_null = true; } } } // If we have additional explicit constraints, evaluate them now. if ($this->spacePHIDs !== null) { $explicit = array(); $explicit_null = false; foreach ($this->spacePHIDs as $phid) { if ($phid === null) { $space = PhabricatorSpacesNamespaceQuery::getDefaultSpace(); } else { $space = idx($all, $phid); } if ($space) { $phid = $space->getPHID(); $explicit[$phid] = $phid; if ($space->getIsDefaultNamespace()) { $explicit_null = true; } } } // If the viewer can see the default space but it isn't on the explicit // list of spaces to query, don't match it. if ($include_null && !$explicit_null) { $include_null = false; } // Include only the spaces common to the viewer and the constraints. $space_phids = array_intersect_key($space_phids, $explicit); } if (!$space_phids && !$include_null) { if ($this->spacePHIDs === null) { throw new PhabricatorEmptyQueryException(pht('You do not have access to any spaces.')); } else { throw new PhabricatorEmptyQueryException(pht('You do not have access to any of the spaces this query ' . 'is constrained to.')); } } $alias = $this->getPrimaryTableAlias(); if ($alias) { $col = qsprintf($conn, '%T.spacePHID', $alias); } else { $col = 'spacePHID'; } if ($space_phids && $include_null) { return qsprintf($conn, '(%Q IN (%Ls) OR %Q IS NULL)', $col, $space_phids, $col); } else { if ($space_phids) { return qsprintf($conn, '%Q IN (%Ls)', $col, $space_phids); } else { return qsprintf($conn, '%Q IS NULL', $col); } } }