[ Index ] |
PHP Cross Reference of Phabricator |
[Summary view] [Print] [Text view]
1 <?php 2 3 final class PhabricatorPolicyEditController 4 extends PhabricatorPolicyController { 5 6 private $phid; 7 8 public function willProcessRequest(array $data) { 9 $this->phid = idx($data, 'phid'); 10 } 11 12 public function processRequest() { 13 $request = $this->getRequest(); 14 $viewer = $request->getUser(); 15 16 $action_options = array( 17 PhabricatorPolicy::ACTION_ALLOW => pht('Allow'), 18 PhabricatorPolicy::ACTION_DENY => pht('Deny'), 19 ); 20 21 $rules = id(new PhutilSymbolLoader()) 22 ->setAncestorClass('PhabricatorPolicyRule') 23 ->loadObjects(); 24 $rules = msort($rules, 'getRuleOrder'); 25 26 $default_rule = array( 27 'action' => head_key($action_options), 28 'rule' => head_key($rules), 29 'value' => null, 30 ); 31 32 if ($this->phid) { 33 $policies = id(new PhabricatorPolicyQuery()) 34 ->setViewer($viewer) 35 ->withPHIDs(array($this->phid)) 36 ->execute(); 37 if (!$policies) { 38 return new Aphront404Response(); 39 } 40 $policy = head($policies); 41 } else { 42 $policy = id(new PhabricatorPolicy()) 43 ->setRules(array($default_rule)) 44 ->setDefaultAction(PhabricatorPolicy::ACTION_DENY); 45 } 46 47 $root_id = celerity_generate_unique_node_id(); 48 49 $default_action = $policy->getDefaultAction(); 50 $rule_data = $policy->getRules(); 51 52 $errors = array(); 53 if ($request->isFormPost()) { 54 $data = $request->getStr('rules'); 55 $data = @json_decode($data, true); 56 if (!is_array($data)) { 57 throw new Exception('Failed to JSON decode rule data!'); 58 } 59 60 $rule_data = array(); 61 foreach ($data as $rule) { 62 $action = idx($rule, 'action'); 63 switch ($action) { 64 case 'allow': 65 case 'deny': 66 break; 67 default: 68 throw new Exception("Invalid action '{$action}'!"); 69 } 70 71 $rule_class = idx($rule, 'rule'); 72 if (empty($rules[$rule_class])) { 73 throw new Exception("Invalid rule class '{$rule_class}'!"); 74 } 75 76 $rule_obj = $rules[$rule_class]; 77 78 $value = $rule_obj->getValueForStorage(idx($rule, 'value')); 79 80 $rule_data[] = array( 81 'action' => $action, 82 'rule' => $rule_class, 83 'value' => $value, 84 ); 85 } 86 87 // Filter out nonsense rules, like a "users" rule without any users 88 // actually specified. 89 $valid_rules = array(); 90 foreach ($rule_data as $rule) { 91 $rule_class = $rule['rule']; 92 if ($rules[$rule_class]->ruleHasEffect($rule['value'])) { 93 $valid_rules[] = $rule; 94 } 95 } 96 97 if (!$valid_rules) { 98 $errors[] = pht('None of these policy rules have any effect.'); 99 } 100 101 // NOTE: Policies are immutable once created, and we always create a new 102 // policy here. If we didn't, we would need to lock this endpoint down, 103 // as users could otherwise just go edit the policies of objects with 104 // custom policies. 105 106 if (!$errors) { 107 $new_policy = new PhabricatorPolicy(); 108 $new_policy->setRules($valid_rules); 109 $new_policy->setDefaultAction($request->getStr('default')); 110 $new_policy->save(); 111 112 $data = array( 113 'phid' => $new_policy->getPHID(), 114 'info' => array( 115 'name' => $new_policy->getName(), 116 'full' => $new_policy->getName(), 117 'icon' => $new_policy->getIcon(), 118 ), 119 ); 120 121 return id(new AphrontAjaxResponse())->setContent($data); 122 } 123 } 124 125 // Convert rule values to display format (for example, expanding PHIDs 126 // into tokens). 127 foreach ($rule_data as $key => $rule) { 128 $rule_data[$key]['value'] = $rules[$rule['rule']]->getValueForDisplay( 129 $viewer, 130 $rule['value']); 131 } 132 133 $default_select = AphrontFormSelectControl::renderSelectTag( 134 $default_action, 135 $action_options, 136 array( 137 'name' => 'default', 138 )); 139 140 if ($errors) { 141 $errors = id(new AphrontErrorView()) 142 ->setErrors($errors); 143 } 144 145 $form = id(new PHUIFormLayoutView()) 146 ->appendChild($errors) 147 ->appendChild( 148 javelin_tag( 149 'input', 150 array( 151 'type' => 'hidden', 152 'name' => 'rules', 153 'sigil' => 'rules', 154 ))) 155 ->appendChild( 156 id(new PHUIFormInsetView()) 157 ->setTitle(pht('Rules')) 158 ->setRightButton( 159 javelin_tag( 160 'a', 161 array( 162 'href' => '#', 163 'class' => 'button green', 164 'sigil' => 'create-rule', 165 'mustcapture' => true, 166 ), 167 pht('New Rule'))) 168 ->setDescription( 169 pht('These rules are processed in order.')) 170 ->setContent(javelin_tag( 171 'table', 172 array( 173 'sigil' => 'rules', 174 'class' => 'policy-rules-table', 175 ), 176 ''))) 177 ->appendChild( 178 id(new AphrontFormMarkupControl()) 179 ->setLabel(pht('If No Rules Match')) 180 ->setValue(pht( 181 '%s all other users.', 182 $default_select))); 183 184 $form = phutil_tag( 185 'div', 186 array( 187 'id' => $root_id, 188 ), 189 $form); 190 191 $rule_options = mpull($rules, 'getRuleDescription'); 192 $type_map = mpull($rules, 'getValueControlType'); 193 $templates = mpull($rules, 'getValueControlTemplate'); 194 195 require_celerity_resource('policy-edit-css'); 196 Javelin::initBehavior( 197 'policy-rule-editor', 198 array( 199 'rootID' => $root_id, 200 'actions' => $action_options, 201 'rules' => $rule_options, 202 'types' => $type_map, 203 'templates' => $templates, 204 'data' => $rule_data, 205 'defaultRule' => $default_rule, 206 )); 207 208 $dialog = id(new AphrontDialogView()) 209 ->setWidth(AphrontDialogView::WIDTH_FULL) 210 ->setUser($viewer) 211 ->setTitle(pht('Edit Policy')) 212 ->appendChild($form) 213 ->addSubmitButton(pht('Save Policy')) 214 ->addCancelButton('#'); 215 216 return id(new AphrontDialogResponse())->setDialog($dialog); 217 } 218 219 }
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 |