Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F14025062
D9199.id.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
7 KB
Referenced Files
None
Subscribers
None
D9199.id.diff
View Options
diff --git a/src/applications/phriction/controller/PhrictionDocumentController.php b/src/applications/phriction/controller/PhrictionDocumentController.php
--- a/src/applications/phriction/controller/PhrictionDocumentController.php
+++ b/src/applications/phriction/controller/PhrictionDocumentController.php
@@ -1,8 +1,5 @@
<?php
-/**
- * @group phriction
- */
final class PhrictionDocumentController
extends PhrictionController {
@@ -118,7 +115,7 @@
$new_doc = id(new PhrictionDocumentQuery())
->setViewer($user)
->withIDs(array($new_doc_id))
- ->exectueOne();
+ ->executeOne();
$slug_uri = PhrictionDocument::getSlugURI($new_doc->getSlug());
diff --git a/src/applications/phriction/phid/PhrictionPHIDTypeDocument.php b/src/applications/phriction/phid/PhrictionPHIDTypeDocument.php
--- a/src/applications/phriction/phid/PhrictionPHIDTypeDocument.php
+++ b/src/applications/phriction/phid/PhrictionPHIDTypeDocument.php
@@ -25,8 +25,8 @@
array $phids) {
return id(new PhrictionDocumentQuery())
- ->needContent(true)
- ->withPHIDs($phids);
+ ->withPHIDs($phids)
+ ->needContent(true);
}
public function loadHandles(
diff --git a/src/applications/phriction/query/PhrictionDocumentQuery.php b/src/applications/phriction/query/PhrictionDocumentQuery.php
--- a/src/applications/phriction/query/PhrictionDocumentQuery.php
+++ b/src/applications/phriction/query/PhrictionDocumentQuery.php
@@ -49,21 +49,97 @@
}
protected function loadPage() {
- $document = new PhrictionDocument();
- $conn_r = $document->establishConnection('r');
+ $table = new PhrictionDocument();
+ $conn_r = $table->establishConnection('r');
$rows = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
- $document->getTableName(),
+ $table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
- return $document->loadAllFromArray($rows);
+ $documents = $table->loadAllFromArray($rows);
+
+ if ($documents) {
+ $ancestor_slugs = array();
+ foreach ($documents as $key => $document) {
+ $document_slug = $document->getSlug();
+ foreach (PhabricatorSlug::getAncestry($document_slug) as $ancestor) {
+ $ancestor_slugs[$ancestor][] = $key;
+ }
+ }
+
+ if ($ancestor_slugs) {
+ $ancestors = queryfx_all(
+ $conn_r,
+ 'SELECT * FROM %T WHERE slug IN (%Ls)',
+ $document->getTableName(),
+ array_keys($ancestor_slugs));
+ $ancestors = $table->loadAllFromArray($ancestors);
+ $ancestors = mpull($ancestors, null, 'getSlug');
+
+ foreach ($ancestor_slugs as $ancestor_slug => $document_keys) {
+ $ancestor = idx($ancestors, $ancestor_slug);
+ foreach ($document_keys as $document_key) {
+ $documents[$document_key]->attachAncestor(
+ $ancestor_slug,
+ $ancestor);
+ }
+ }
+ }
+ }
+
+ return $documents;
}
protected function willFilterPage(array $documents) {
+ // To view a Phriction document, you must also be able to view all of the
+ // ancestor documents. Filter out documents which have ancestors that are
+ // not visible.
+
+ $document_map = array();
+ foreach ($documents as $document) {
+ $document_map[$document->getSlug()] = $document;
+ foreach ($document->getAncestors() as $key => $ancestor) {
+ if ($ancestor) {
+ $document_map[$key] = $ancestor;
+ }
+ }
+ }
+
+ $filtered_map = $this->applyPolicyFilter(
+ $document_map,
+ array(PhabricatorPolicyCapability::CAN_VIEW));
+
+ // Filter all of the documents where a parent is not visible.
+ foreach ($documents as $document_key => $document) {
+ // If the document itself is not visible, filter it.
+ if (!isset($filtered_map[$document->getSlug()])) {
+ $this->didRejectResult($documents[$document_key]);
+ unset($documents[$document_key]);
+ continue;
+ }
+
+ // If an ancestor exists but is not visible, filter the document.
+ foreach ($document->getAncestors() as $ancestor_key => $ancestor) {
+ if (!$ancestor) {
+ continue;
+ }
+
+ if (!isset($filtered_map[$ancestor_key])) {
+ $this->didRejectResult($documents[$document_key]);
+ unset($documents[$document_key]);
+ break;
+ }
+ }
+ }
+
+ if (!$documents) {
+ return $documents;
+ }
+
if ($this->needContent) {
$contents = id(new PhrictionContent())->loadAllWhere(
'id IN (%Ld)',
diff --git a/src/applications/phriction/storage/PhrictionDocument.php b/src/applications/phriction/storage/PhrictionDocument.php
--- a/src/applications/phriction/storage/PhrictionDocument.php
+++ b/src/applications/phriction/storage/PhrictionDocument.php
@@ -1,8 +1,5 @@
<?php
-/**
- * @group phriction
- */
final class PhrictionDocument extends PhrictionDAO
implements
PhabricatorPolicyInterface,
@@ -16,6 +13,7 @@
protected $status;
private $contentObject = self::ATTACHABLE;
+ private $ancestors = array();
// TODO: This should be `self::ATTACHABLE`, but there are still a lot of call
// sites which load PhrictionDocuments directly.
@@ -84,6 +82,19 @@
return (bool)$this->getProject();
}
+ public function getAncestors() {
+ return $this->ancestors;
+ }
+
+ public function getAncestor($slug) {
+ return $this->assertAttachedKey($this->ancestors, $slug);
+ }
+
+ public function attachAncestor($slug, $ancestor) {
+ $this->ancestors[$slug] = $ancestor;
+ return $this;
+ }
+
public static function isProjectSlug($slug) {
$slug = PhabricatorSlug::normalize($slug);
$prefix = 'projects/';
@@ -119,6 +130,7 @@
if ($this->hasProject()) {
return $this->getProject()->getPolicy($capability);
}
+
return PhabricatorPolicies::POLICY_USER;
}
@@ -134,6 +146,14 @@
return pht(
"This is a project wiki page, and inherits the project's policies.");
}
+
+ switch ($capability) {
+ case PhabricatorPolicyCapability::CAN_VIEW:
+ return pht(
+ 'To view a wiki document, you must also be able to view all '.
+ 'of its parents.');
+ }
+
return null;
}
diff --git a/src/infrastructure/query/policy/PhabricatorPolicyAwareQuery.php b/src/infrastructure/query/policy/PhabricatorPolicyAwareQuery.php
--- a/src/infrastructure/query/policy/PhabricatorPolicyAwareQuery.php
+++ b/src/infrastructure/query/policy/PhabricatorPolicyAwareQuery.php
@@ -302,19 +302,32 @@
private function getPolicyFilter() {
$filter = new PhabricatorPolicyFilter();
$filter->setViewer($this->viewer);
- if (!$this->capabilities) {
- $capabilities = array(
- PhabricatorPolicyCapability::CAN_VIEW,
- );
- } else {
- $capabilities = $this->capabilities;
- }
+ $capabilities = $this->getRequiredCapabilities();
$filter->requireCapabilities($capabilities);
$filter->raisePolicyExceptions($this->shouldRaisePolicyExceptions());
return $filter;
}
+ protected function getRequiredCapabilities() {
+ if ($this->capabilities) {
+ return $this->capabilities;
+ }
+
+ return array(
+ PhabricatorPolicyCapability::CAN_VIEW,
+ );
+ }
+
+ protected function applyPolicyFilter(array $objects, array $capabilities) {
+ if ($this->shouldDisablePolicyFiltering()) {
+ return $objects;
+ }
+ $filter = $this->getPolicyFilter();
+ $filter->requireCapabilities($capabilities);
+ return $filter->apply($objects);
+ }
+
protected function didRejectResult(PhabricatorPolicyInterface $object) {
$this->getPolicyFilter()->rejectObject(
$object,
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Nov 8, 2:13 PM (1 w, 4 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6743890
Default Alt Text
D9199.id.diff (7 KB)
Attached To
Mode
D9199: Apply hierarchical policy checks to Phriction
Attached
Detach File
Event Timeline
Log In to Comment