[ Index ] |
PHP Cross Reference of Phabricator |
[Summary view] [Print] [Text view]
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 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Sun Nov 30 09:20:46 2014 | Cross-referenced by PHPXref 0.7.1 |