1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-09-20 09:18:48 +02:00

Provide an attached-to-visible-object policy exception for files

Summary:
Ref T603. This uses the existing edges (from Conpherence) to record that a file is attached to an object, and uses those edges to create a policy exception: if you can view an attached object, you can view a file.

I'm going to combine this with restrictive defaults to satisfy the other half of the equation (that files you attach to a conpherence usually shouldn't be public by default).

Test Plan:
  - Loaded `/files/`.
  - Uploaded a file to a Conpherence, looked at it in Files, saw the attachment.

Reviewers: btrahan

Reviewed By: btrahan

CC: aran

Maniphest Tasks: T603

Differential Revision: https://secure.phabricator.com/D7182
This commit is contained in:
epriestley 2013-10-01 08:43:34 -07:00
parent fc57995330
commit 472be5e26e
3 changed files with 105 additions and 3 deletions

View file

@ -27,7 +27,11 @@ final class PhabricatorFileInfoController extends PhabricatorFileController {
->withObjectPHIDs(array($phid))
->execute();
$this->loadHandles(array($file->getAuthorPHID()));
$handle_phids = array_merge(
array($file->getAuthorPHID()),
$file->getObjectPHIDs());
$this->loadHandles($handle_phids);
$header = id(new PHUIHeaderView())
->setHeader($file->getName());
@ -207,6 +211,15 @@ final class PhabricatorFileInfoController extends PhabricatorFileController {
}
}
$phids = $file->getObjectPHIDs();
if ($phids) {
$view->addSectionHeader(pht('Attached'));
$view->addProperty(
pht('Attached To'),
$this->renderHandlesForPHIDs($phids));
}
if ($file->isViewableImage()) {
$image = phutil_tag(

View file

@ -104,7 +104,48 @@ final class PhabricatorFileQuery
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
$files = $table->loadAllFromArray($data);
if (!$files) {
return $files;
}
// We need to load attached objects to perform policy checks for files.
// First, load the edges.
$edge_type = PhabricatorEdgeConfig::TYPE_FILE_HAS_OBJECT;
$phids = mpull($files, 'getPHID');
$edges = id(new PhabricatorEdgeQuery())
->withSourcePHIDs($phids)
->withEdgeTypes(array($edge_type))
->execute();
$object_phids = array();
foreach ($files as $file) {
$phids = array_keys($edges[$file->getPHID()][$edge_type]);
$file->attachObjectPHIDs($phids);
foreach ($phids as $phid) {
$object_phids[$phid] = true;
}
}
// Now, load the objects.
$objects = array();
if ($object_phids) {
$objects = id(new PhabricatorObjectQuery())
->setViewer($this->getViewer())
->withPHIDs($object_phids)
->execute();
$objects = mpull($objects, null, 'getPHID');
}
foreach ($files as $file) {
$file_objects = array_select_keys($objects, $file->getObjectPHIDs());
$file->attachObjects($file_objects);
}
return $files;
}
private function buildJoinClause(AphrontDatabaseConnection $conn_r) {

View file

@ -31,6 +31,9 @@ final class PhabricatorFile extends PhabricatorFileDAO
protected $ttl;
protected $isExplicitUpload = 1;
private $objects = self::ATTACHABLE;
private $objectPHIDs = self::ATTACHABLE;
public function getConfiguration() {
return array(
self::CONFIG_AUX_PHID => true,
@ -803,6 +806,9 @@ final class PhabricatorFile extends PhabricatorFileDAO
->save();
unset($unguarded);
$file->attachObjectPHIDs(array());
$file->attachObjects(array());
$files[$name] = $file;
}
@ -821,6 +827,24 @@ final class PhabricatorFile extends PhabricatorFileDAO
return idx(self::loadBuiltins($user, array($name)), $name);
}
public function getObjects() {
return $this->assertAttached($this->objects);
}
public function attachObjects(array $objects) {
$this->objects = $objects;
return $this;
}
public function getObjectPHIDs() {
return $this->assertAttached($this->objectPHIDs);
}
public function attachObjectPHIDs(array $object_phids) {
$this->objectPHIDs = $object_phids;
return $this;
}
/* -( PhabricatorPolicyInterface Implementation )-------------------------- */
@ -838,11 +862,35 @@ final class PhabricatorFile extends PhabricatorFileDAO
}
public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
$viewer_phid = $viewer->getPHID();
if ($viewer_phid) {
if ($this->getAuthorPHID() == $viewer_phid) {
return true;
}
}
switch ($capability) {
case PhabricatorPolicyCapability::CAN_VIEW:
// If you can see any object this file is attached to, you can see
// the file.
return (count($this->getObjects()) > 0);
}
return false;
}
public function describeAutomaticCapability($capability) {
return null;
$out = array();
$out[] = pht('The user who uploaded a file can always view and edit it.');
switch ($capability) {
case PhabricatorPolicyCapability::CAN_VIEW:
$out[] = pht(
'Files attached to objects are visible to users who can view '.
'those objects.');
break;
}
return $out;
}