mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-15 19:32:40 +01:00
b902005bed
Summary: Ref T603. Killing this class is cool because the classes that replace it are policy-aware. Tried to keep my wits about me as I did this and fixed a few random things along the way. (Ones I remember right now are pulling a query outside of a foreach loop in Releeph and fixing the text in UIExample to note that the ace of hearts if "a powerful" card and not the "most powerful" card (Q of spades gets that honor IMO)) Test Plan: tested the first few changes (execute, executeOne X handle, object) then got real mechanical / careful with the other changes. Reviewers: epriestley Reviewed By: epriestley CC: Korvin, aran, FacebookPOC Maniphest Tasks: T603 Differential Revision: https://secure.phabricator.com/D6941
171 lines
4.7 KiB
PHP
171 lines
4.7 KiB
PHP
<?php
|
|
|
|
final class PhabricatorPolicyQuery extends PhabricatorQuery {
|
|
|
|
private $viewer;
|
|
private $object;
|
|
|
|
public function setViewer(PhabricatorUser $viewer) {
|
|
$this->viewer = $viewer;
|
|
return $this;
|
|
}
|
|
|
|
public function setObject(PhabricatorPolicyInterface $object) {
|
|
$this->object = $object;
|
|
return $this;
|
|
}
|
|
|
|
public static function renderPolicyDescriptions(
|
|
PhabricatorUser $viewer,
|
|
PhabricatorPolicyInterface $object) {
|
|
|
|
$results = array();
|
|
$policies = null;
|
|
$global = self::getGlobalPolicies();
|
|
|
|
$capabilities = $object->getCapabilities();
|
|
foreach ($capabilities as $capability) {
|
|
$policy = $object->getPolicy($capability);
|
|
if (!$policy) {
|
|
continue;
|
|
}
|
|
|
|
if (isset($global[$policy])) {
|
|
$results[$capability] = $global[$policy]->renderDescription();
|
|
continue;
|
|
}
|
|
|
|
if ($policies === null) {
|
|
// This slightly overfetches data, but it shouldn't generally
|
|
// be a problem.
|
|
$policies = id(new PhabricatorPolicyQuery())
|
|
->setViewer($viewer)
|
|
->setObject($object)
|
|
->execute();
|
|
}
|
|
|
|
$results[$capability] = $policies[$policy]->renderDescription();
|
|
}
|
|
|
|
return $results;
|
|
}
|
|
|
|
public function execute() {
|
|
if (!$this->viewer) {
|
|
throw new Exception('Call setViewer() before execute()!');
|
|
}
|
|
if (!$this->object) {
|
|
throw new Exception('Call setObject() before execute()!');
|
|
}
|
|
|
|
$results = $this->getGlobalPolicies();
|
|
|
|
if ($this->viewer->getPHID()) {
|
|
$projects = id(new PhabricatorProjectQuery())
|
|
->setViewer($this->viewer)
|
|
->withMemberPHIDs(array($this->viewer->getPHID()))
|
|
->execute();
|
|
if ($projects) {
|
|
foreach ($projects as $project) {
|
|
$results[] = id(new PhabricatorPolicy())
|
|
->setType(PhabricatorPolicyType::TYPE_PROJECT)
|
|
->setPHID($project->getPHID())
|
|
->setHref('/project/view/'.$project->getID().'/')
|
|
->setName($project->getName());
|
|
}
|
|
}
|
|
}
|
|
|
|
$results = mpull($results, null, 'getPHID');
|
|
|
|
$other_policies = array();
|
|
$capabilities = $this->object->getCapabilities();
|
|
foreach ($capabilities as $capability) {
|
|
$policy = $this->object->getPolicy($capability);
|
|
if (!$policy) {
|
|
continue;
|
|
}
|
|
$other_policies[$policy] = $policy;
|
|
}
|
|
|
|
// If this install doesn't have "Public" enabled, remove it as an option
|
|
// unless the object already has a "Public" policy. In this case we retain
|
|
// the policy but enforce it as thought it was "All Users".
|
|
$show_public = PhabricatorEnv::getEnvConfig('policy.allow-public');
|
|
if (!$show_public &&
|
|
empty($other_policies[PhabricatorPolicies::POLICY_PUBLIC])) {
|
|
unset($results[PhabricatorPolicies::POLICY_PUBLIC]);
|
|
}
|
|
|
|
$other_policies = array_diff_key($other_policies, $results);
|
|
|
|
if ($other_policies) {
|
|
$handles = id(new PhabricatorHandleQuery())
|
|
->setViewer($this->viewer)
|
|
->withPHIDs($other_policies)
|
|
->execute();
|
|
foreach ($other_policies as $phid) {
|
|
$results[$phid] = PhabricatorPolicy::newFromPolicyAndHandle(
|
|
$phid,
|
|
$handles[$phid]);
|
|
}
|
|
}
|
|
|
|
$results = msort($results, 'getSortKey');
|
|
|
|
return $results;
|
|
}
|
|
|
|
public static function isGlobalPolicy($policy) {
|
|
$globalPolicies = self::getGlobalPolicies();
|
|
|
|
if (isset($globalPolicies[$policy])) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public static function getGlobalPolicy($policy) {
|
|
if (!self::isGlobalPolicy($policy)) {
|
|
throw new Exception("Policy '{$policy}' is not a global policy!");
|
|
}
|
|
return idx(self::getGlobalPolicies(), $policy);
|
|
}
|
|
|
|
private static function getGlobalPolicies() {
|
|
static $constants = array(
|
|
PhabricatorPolicies::POLICY_PUBLIC,
|
|
PhabricatorPolicies::POLICY_USER,
|
|
PhabricatorPolicies::POLICY_ADMIN,
|
|
PhabricatorPolicies::POLICY_NOONE,
|
|
);
|
|
|
|
$results = array();
|
|
foreach ($constants as $constant) {
|
|
$results[$constant] = id(new PhabricatorPolicy())
|
|
->setType(PhabricatorPolicyType::TYPE_GLOBAL)
|
|
->setPHID($constant)
|
|
->setName(self::getGlobalPolicyName($constant));
|
|
}
|
|
|
|
return $results;
|
|
}
|
|
|
|
private static function getGlobalPolicyName($policy) {
|
|
switch ($policy) {
|
|
case PhabricatorPolicies::POLICY_PUBLIC:
|
|
return pht('Public (No Login Required)');
|
|
case PhabricatorPolicies::POLICY_USER:
|
|
return pht('All Users');
|
|
case PhabricatorPolicies::POLICY_ADMIN:
|
|
return pht('Administrators');
|
|
case PhabricatorPolicies::POLICY_NOONE:
|
|
return pht('No One');
|
|
default:
|
|
return pht('Unknown Policy');
|
|
}
|
|
}
|
|
|
|
}
|
|
|