[ Index ]

PHP Cross Reference of Phabricator

title

Body

[close]

/src/applications/policy/controller/ -> PhabricatorPolicyEditController.php (source)

   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  }


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