[ Index ]

PHP Cross Reference of Phabricator

title

Body

[close]

/src/applications/policy/storage/ -> PhabricatorPolicy.php (source)

   1  <?php
   2  
   3  final class PhabricatorPolicy
   4    extends PhabricatorPolicyDAO
   5    implements PhabricatorPolicyInterface {
   6  
   7    const ACTION_ALLOW = 'allow';
   8    const ACTION_DENY = 'deny';
   9  
  10    private $name;
  11    private $shortName;
  12    private $type;
  13    private $href;
  14    private $workflow;
  15    private $icon;
  16  
  17    protected $rules = array();
  18    protected $defaultAction = self::ACTION_DENY;
  19  
  20    private $ruleObjects = self::ATTACHABLE;
  21  
  22    public function getConfiguration() {
  23      return array(
  24        self::CONFIG_AUX_PHID => true,
  25        self::CONFIG_SERIALIZATION => array(
  26          'rules' => self::SERIALIZATION_JSON,
  27        ),
  28        self::CONFIG_COLUMN_SCHEMA => array(
  29          'defaultAction' => 'text32',
  30        ),
  31        self::CONFIG_KEY_SCHEMA => array(
  32          'key_phid' => null,
  33          'phid' => array(
  34            'columns' => array('phid'),
  35            'unique' => true,
  36          ),
  37        ),
  38      ) + parent::getConfiguration();
  39    }
  40  
  41    public function generatePHID() {
  42      return PhabricatorPHID::generateNewPHID(
  43        PhabricatorPolicyPHIDTypePolicy::TYPECONST);
  44    }
  45  
  46    public static function newFromPolicyAndHandle(
  47      $policy_identifier,
  48      PhabricatorObjectHandle $handle = null) {
  49  
  50      $is_global = PhabricatorPolicyQuery::isGlobalPolicy($policy_identifier);
  51      if ($is_global) {
  52        return PhabricatorPolicyQuery::getGlobalPolicy($policy_identifier);
  53      }
  54  
  55      if (!$handle) {
  56        throw new Exception(
  57          "Policy identifier is an object PHID ('{$policy_identifier}'), but no ".
  58          "object handle was provided. A handle must be provided for object ".
  59          "policies.");
  60      }
  61  
  62      $handle_phid = $handle->getPHID();
  63      if ($policy_identifier != $handle_phid) {
  64        throw new Exception(
  65          "Policy identifier is an object PHID ('{$policy_identifier}'), but ".
  66          "the provided handle has a different PHID ('{$handle_phid}'). The ".
  67          "handle must correspond to the policy identifier.");
  68      }
  69  
  70      $policy = id(new PhabricatorPolicy())
  71        ->setPHID($policy_identifier)
  72        ->setHref($handle->getURI());
  73  
  74      $phid_type = phid_get_type($policy_identifier);
  75      switch ($phid_type) {
  76        case PhabricatorProjectProjectPHIDType::TYPECONST:
  77          $policy->setType(PhabricatorPolicyType::TYPE_PROJECT);
  78          $policy->setName($handle->getName());
  79          break;
  80        case PhabricatorPeopleUserPHIDType::TYPECONST:
  81          $policy->setType(PhabricatorPolicyType::TYPE_USER);
  82          $policy->setName($handle->getFullName());
  83          break;
  84        case PhabricatorPolicyPHIDTypePolicy::TYPECONST:
  85          // TODO: This creates a weird handle-based version of a rule policy.
  86          // It behaves correctly, but can't be applied since it doesn't have
  87          // any rules. It is used to render transactions, and might need some
  88          // cleanup.
  89          break;
  90        default:
  91          $policy->setType(PhabricatorPolicyType::TYPE_MASKED);
  92          $policy->setName($handle->getFullName());
  93          break;
  94      }
  95  
  96      $policy->makeEphemeral();
  97  
  98      return $policy;
  99    }
 100  
 101    public function setType($type) {
 102      $this->type = $type;
 103      return $this;
 104    }
 105  
 106    public function getType() {
 107      if (!$this->type) {
 108        return PhabricatorPolicyType::TYPE_CUSTOM;
 109      }
 110      return $this->type;
 111    }
 112  
 113    public function setName($name) {
 114      $this->name = $name;
 115      return $this;
 116    }
 117  
 118    public function getName() {
 119      if (!$this->name) {
 120        return pht('Custom Policy');
 121      }
 122      return $this->name;
 123    }
 124  
 125    public function setShortName($short_name) {
 126      $this->shortName = $short_name;
 127      return $this;
 128    }
 129  
 130    public function getShortName() {
 131      if ($this->shortName) {
 132        return $this->shortName;
 133      }
 134      return $this->getName();
 135    }
 136  
 137    public function setHref($href) {
 138      $this->href = $href;
 139      return $this;
 140    }
 141  
 142    public function getHref() {
 143      return $this->href;
 144    }
 145  
 146    public function setWorkflow($workflow) {
 147      $this->workflow = $workflow;
 148      return $this;
 149    }
 150  
 151    public function getWorkflow() {
 152      return $this->workflow;
 153    }
 154  
 155    public function getIcon() {
 156      switch ($this->getType()) {
 157        case PhabricatorPolicyType::TYPE_GLOBAL:
 158          static $map = array(
 159            PhabricatorPolicies::POLICY_PUBLIC  => 'fa-globe',
 160            PhabricatorPolicies::POLICY_USER    => 'fa-users',
 161            PhabricatorPolicies::POLICY_ADMIN   => 'fa-eye',
 162            PhabricatorPolicies::POLICY_NOONE   => 'fa-ban',
 163          );
 164          return idx($map, $this->getPHID(), 'fa-question-circle');
 165        case PhabricatorPolicyType::TYPE_USER:
 166          return 'fa-user';
 167        case PhabricatorPolicyType::TYPE_PROJECT:
 168          return 'fa-briefcase';
 169        case PhabricatorPolicyType::TYPE_CUSTOM:
 170        case PhabricatorPolicyType::TYPE_MASKED:
 171          return 'fa-certificate';
 172        default:
 173          return 'fa-question-circle';
 174      }
 175    }
 176  
 177    public function getSortKey() {
 178      return sprintf(
 179        '%02d%s',
 180        PhabricatorPolicyType::getPolicyTypeOrder($this->getType()),
 181        $this->getSortName());
 182    }
 183  
 184    private function getSortName() {
 185      if ($this->getType() == PhabricatorPolicyType::TYPE_GLOBAL) {
 186        static $map = array(
 187          PhabricatorPolicies::POLICY_PUBLIC  => 0,
 188          PhabricatorPolicies::POLICY_USER    => 1,
 189          PhabricatorPolicies::POLICY_ADMIN   => 2,
 190          PhabricatorPolicies::POLICY_NOONE   => 3,
 191        );
 192        return idx($map, $this->getPHID());
 193      }
 194      return $this->getName();
 195    }
 196  
 197    public static function getPolicyExplanation(
 198      PhabricatorUser $viewer,
 199      $policy) {
 200  
 201      switch ($policy) {
 202        case PhabricatorPolicies::POLICY_PUBLIC:
 203          return pht('This object is public.');
 204        case PhabricatorPolicies::POLICY_USER:
 205          return pht('Logged in users can take this action.');
 206        case PhabricatorPolicies::POLICY_ADMIN:
 207          return pht('Administrators can take this action.');
 208        case PhabricatorPolicies::POLICY_NOONE:
 209          return pht('By default, no one can take this action.');
 210        default:
 211          $handle = id(new PhabricatorHandleQuery())
 212            ->setViewer($viewer)
 213            ->withPHIDs(array($policy))
 214            ->executeOne();
 215  
 216          $type = phid_get_type($policy);
 217          if ($type == PhabricatorProjectProjectPHIDType::TYPECONST) {
 218            return pht(
 219              'Members of the project "%s" can take this action.',
 220              $handle->getFullName());
 221          } else if ($type == PhabricatorPeopleUserPHIDType::TYPECONST) {
 222            return pht(
 223              '%s can take this action.',
 224              $handle->getFullName());
 225          } else if ($type == PhabricatorPolicyPHIDTypePolicy::TYPECONST) {
 226            return pht(
 227              'This object has a custom policy controlling who can take this '.
 228              'action.');
 229          } else {
 230            return pht(
 231              'This object has an unknown or invalid policy setting ("%s").',
 232              $policy);
 233          }
 234      }
 235    }
 236  
 237    public function getFullName() {
 238      switch ($this->getType()) {
 239        case PhabricatorPolicyType::TYPE_PROJECT:
 240          return pht('Project: %s', $this->getName());
 241        case PhabricatorPolicyType::TYPE_MASKED:
 242          return pht('Other: %s', $this->getName());
 243        default:
 244          return $this->getName();
 245      }
 246    }
 247  
 248    public function renderDescription($icon = false) {
 249      $img = null;
 250      if ($icon) {
 251        $img = id(new PHUIIconView())
 252          ->setIconFont($this->getIcon());
 253      }
 254  
 255      if ($this->getHref()) {
 256        $desc = javelin_tag(
 257          'a',
 258          array(
 259            'href' => $this->getHref(),
 260            'class' => 'policy-link',
 261            'sigil' => $this->getWorkflow() ? 'workflow' : null,
 262          ),
 263          array(
 264            $img,
 265            $this->getName(),
 266          ));
 267      } else {
 268        if ($img) {
 269          $desc = array($img, $this->getName());
 270        } else {
 271          $desc = $this->getName();
 272        }
 273      }
 274  
 275      switch ($this->getType()) {
 276        case PhabricatorPolicyType::TYPE_PROJECT:
 277          return pht('%s (Project)', $desc);
 278        case PhabricatorPolicyType::TYPE_CUSTOM:
 279          return $desc;
 280        case PhabricatorPolicyType::TYPE_MASKED:
 281          return pht(
 282            '%s (You do not have permission to view policy details.)',
 283            $desc);
 284        default:
 285          return $desc;
 286      }
 287    }
 288  
 289    /**
 290     * Return a list of custom rule classes (concrete subclasses of
 291     * @{class:PhabricatorPolicyRule}) this policy uses.
 292     *
 293     * @return list<string> List of class names.
 294     */
 295    public function getCustomRuleClasses() {
 296      $classes = array();
 297  
 298      foreach ($this->getRules() as $rule) {
 299        $class = idx($rule, 'rule');
 300        try {
 301          if (class_exists($class)) {
 302            $classes[$class] = $class;
 303          }
 304        } catch (Exception $ex) {
 305          continue;
 306        }
 307      }
 308  
 309      return array_keys($classes);
 310    }
 311  
 312    /**
 313     * Return a list of all values used by a given rule class to implement this
 314     * policy. This is used to bulk load data (like project memberships) in order
 315     * to apply policy filters efficiently.
 316     *
 317     * @param string Policy rule classname.
 318     * @return list<wild> List of values used in this policy.
 319     */
 320    public function getCustomRuleValues($rule_class) {
 321      $values = array();
 322      foreach ($this->getRules() as $rule) {
 323        if ($rule['rule'] == $rule_class) {
 324          $values[] = $rule['value'];
 325        }
 326      }
 327      return $values;
 328    }
 329  
 330    public function attachRuleObjects(array $objects) {
 331      $this->ruleObjects = $objects;
 332      return $this;
 333    }
 334  
 335    public function getRuleObjects() {
 336      return $this->assertAttached($this->ruleObjects);
 337    }
 338  
 339  
 340  /* -(  PhabricatorPolicyInterface  )----------------------------------------- */
 341  
 342  
 343    public function getCapabilities() {
 344      return array(
 345        PhabricatorPolicyCapability::CAN_VIEW,
 346      );
 347    }
 348  
 349    public function getPolicy($capability) {
 350      // NOTE: We implement policies only so we can comply with the interface.
 351      // The actual query skips them, as enforcing policies on policies seems
 352      // perilous and isn't currently required by the application.
 353      return PhabricatorPolicies::POLICY_PUBLIC;
 354    }
 355  
 356    public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
 357      return false;
 358    }
 359  
 360    public function describeAutomaticCapability($capability) {
 361      return null;
 362    }
 363  
 364  }


Generated: Sun Nov 30 09:20:46 2014 Cross-referenced by PHPXref 0.7.1