[ Index ]

PHP Cross Reference of Phabricator

title

Body

[close]

/src/applications/policy/__tests__/ -> PhabricatorPolicyTestCase.php (source)

   1  <?php
   2  
   3  final class PhabricatorPolicyTestCase extends PhabricatorTestCase {
   4  
   5    /**
   6     * Verify that any user can view an object with POLICY_PUBLIC.
   7     */
   8    public function testPublicPolicyEnabled() {
   9      $env = PhabricatorEnv::beginScopedEnv();
  10      $env->overrideEnvConfig('policy.allow-public', true);
  11  
  12      $this->expectVisibility(
  13        $this->buildObject(PhabricatorPolicies::POLICY_PUBLIC),
  14        array(
  15          'public'  => true,
  16          'user'    => true,
  17          'admin'   => true,
  18        ),
  19        'Public Policy (Enabled in Config)');
  20    }
  21  
  22  
  23    /**
  24     * Verify that POLICY_PUBLIC is interpreted as POLICY_USER when public
  25     * policies are disallowed.
  26     */
  27    public function testPublicPolicyDisabled() {
  28      $env = PhabricatorEnv::beginScopedEnv();
  29      $env->overrideEnvConfig('policy.allow-public', false);
  30  
  31      $this->expectVisibility(
  32        $this->buildObject(PhabricatorPolicies::POLICY_PUBLIC),
  33        array(
  34          'public'  => false,
  35          'user'    => true,
  36          'admin'   => true,
  37        ),
  38        'Public Policy (Disabled in Config)');
  39    }
  40  
  41  
  42    /**
  43     * Verify that any logged-in user can view an object with POLICY_USER, but
  44     * logged-out users can not.
  45     */
  46    public function testUsersPolicy() {
  47      $this->expectVisibility(
  48        $this->buildObject(PhabricatorPolicies::POLICY_USER),
  49        array(
  50          'public'  => false,
  51          'user'    => true,
  52          'admin'   => true,
  53        ),
  54        'User Policy');
  55    }
  56  
  57  
  58    /**
  59     * Verify that only administrators can view an object with POLICY_ADMIN.
  60     */
  61    public function testAdminPolicy() {
  62      $this->expectVisibility(
  63        $this->buildObject(PhabricatorPolicies::POLICY_ADMIN),
  64        array(
  65          'public'  => false,
  66          'user'    => false,
  67          'admin'   => true,
  68        ),
  69        'Admin Policy');
  70    }
  71  
  72  
  73    /**
  74     * Verify that no one can view an object with POLICY_NOONE.
  75     */
  76    public function testNoOnePolicy() {
  77      $this->expectVisibility(
  78        $this->buildObject(PhabricatorPolicies::POLICY_NOONE),
  79        array(
  80          'public'  => false,
  81          'user'    => false,
  82          'admin'   => false,
  83        ),
  84        'No One Policy');
  85    }
  86  
  87  
  88    /**
  89     * Test offset-based filtering.
  90     */
  91    public function testOffsets() {
  92      $results = array(
  93        $this->buildObject(PhabricatorPolicies::POLICY_NOONE),
  94        $this->buildObject(PhabricatorPolicies::POLICY_NOONE),
  95        $this->buildObject(PhabricatorPolicies::POLICY_NOONE),
  96        $this->buildObject(PhabricatorPolicies::POLICY_USER),
  97        $this->buildObject(PhabricatorPolicies::POLICY_USER),
  98        $this->buildObject(PhabricatorPolicies::POLICY_USER),
  99      );
 100  
 101      $query = new PhabricatorPolicyAwareTestQuery();
 102      $query->setResults($results);
 103      $query->setViewer($this->buildUser('user'));
 104  
 105      $this->assertEqual(
 106        3,
 107        count($query->setLimit(3)->setOffset(0)->execute()),
 108        'Invisible objects are ignored.');
 109  
 110      $this->assertEqual(
 111        0,
 112        count($query->setLimit(3)->setOffset(3)->execute()),
 113        'Offset pages through visible objects only.');
 114  
 115      $this->assertEqual(
 116        2,
 117        count($query->setLimit(3)->setOffset(1)->execute()),
 118        'Offsets work correctly.');
 119  
 120      $this->assertEqual(
 121        2,
 122        count($query->setLimit(0)->setOffset(1)->execute()),
 123        'Offset with no limit works.');
 124    }
 125  
 126  
 127    /**
 128     * Test limits.
 129     */
 130    public function testLimits() {
 131      $results = array(
 132        $this->buildObject(PhabricatorPolicies::POLICY_USER),
 133        $this->buildObject(PhabricatorPolicies::POLICY_USER),
 134        $this->buildObject(PhabricatorPolicies::POLICY_USER),
 135        $this->buildObject(PhabricatorPolicies::POLICY_USER),
 136        $this->buildObject(PhabricatorPolicies::POLICY_USER),
 137        $this->buildObject(PhabricatorPolicies::POLICY_USER),
 138      );
 139  
 140      $query = new PhabricatorPolicyAwareTestQuery();
 141      $query->setResults($results);
 142      $query->setViewer($this->buildUser('user'));
 143  
 144      $this->assertEqual(
 145        3,
 146        count($query->setLimit(3)->setOffset(0)->execute()),
 147        'Limits work.');
 148  
 149      $this->assertEqual(
 150        2,
 151        count($query->setLimit(3)->setOffset(4)->execute()),
 152        'Limit + offset work.');
 153    }
 154  
 155  
 156    /**
 157     * Test that omnipotent users bypass policies.
 158     */
 159    public function testOmnipotence() {
 160      $results = array(
 161        $this->buildObject(PhabricatorPolicies::POLICY_NOONE),
 162      );
 163  
 164      $query = new PhabricatorPolicyAwareTestQuery();
 165      $query->setResults($results);
 166      $query->setViewer(PhabricatorUser::getOmnipotentUser());
 167  
 168      $this->assertEqual(
 169        1,
 170        count($query->execute()));
 171    }
 172  
 173  
 174    /**
 175     * Test that invalid policies reject viewers of all types.
 176     */
 177    public function testRejectInvalidPolicy() {
 178      $invalid_policy = 'the duck goes quack';
 179      $object = $this->buildObject($invalid_policy);
 180  
 181      $this->expectVisibility(
 182        $object = $this->buildObject($invalid_policy),
 183        array(
 184          'public'  => false,
 185          'user'    => false,
 186          'admin'   => false,
 187        ),
 188        'Invalid Policy');
 189    }
 190  
 191  
 192    /**
 193     * An omnipotent user should be able to see even objects with invalid
 194     * policies.
 195     */
 196    public function testInvalidPolicyVisibleByOmnipotentUser() {
 197      $invalid_policy = 'the cow goes moo';
 198      $object = $this->buildObject($invalid_policy);
 199  
 200      $results = array(
 201        $object,
 202      );
 203  
 204      $query = new PhabricatorPolicyAwareTestQuery();
 205      $query->setResults($results);
 206      $query->setViewer(PhabricatorUser::getOmnipotentUser());
 207  
 208      $this->assertEqual(
 209        1,
 210        count($query->execute()));
 211    }
 212  
 213    public function testAllQueriesBelongToActualApplications() {
 214      $queries = id(new PhutilSymbolLoader())
 215        ->setAncestorClass('PhabricatorPolicyAwareQuery')
 216        ->loadObjects();
 217  
 218      foreach ($queries as $qclass => $query) {
 219        $class = $query->getQueryApplicationClass();
 220        if (!$class) {
 221          continue;
 222        }
 223        $this->assertTrue(
 224          (bool)PhabricatorApplication::getByClass($class),
 225          "Application class '{$class}' for query '{$qclass}'");
 226      }
 227    }
 228  
 229    public function testMultipleCapabilities() {
 230      $object = new PhabricatorPolicyTestObject();
 231      $object->setCapabilities(
 232        array(
 233          PhabricatorPolicyCapability::CAN_VIEW,
 234          PhabricatorPolicyCapability::CAN_EDIT,
 235        ));
 236      $object->setPolicies(
 237        array(
 238          PhabricatorPolicyCapability::CAN_VIEW
 239            => PhabricatorPolicies::POLICY_USER,
 240          PhabricatorPolicyCapability::CAN_EDIT
 241            => PhabricatorPolicies::POLICY_NOONE,
 242        ));
 243  
 244      $filter = new PhabricatorPolicyFilter();
 245      $filter->requireCapabilities(
 246        array(
 247          PhabricatorPolicyCapability::CAN_VIEW,
 248          PhabricatorPolicyCapability::CAN_EDIT,
 249        ));
 250      $filter->setViewer($this->buildUser('user'));
 251  
 252      $result = $filter->apply(array($object));
 253  
 254      $this->assertEqual(array(), $result);
 255    }
 256  
 257  
 258    /**
 259     * Test an object for visibility across multiple user specifications.
 260     */
 261    private function expectVisibility(
 262      PhabricatorPolicyTestObject $object,
 263      array $map,
 264      $description) {
 265  
 266      foreach ($map as $spec => $expect) {
 267        $viewer = $this->buildUser($spec);
 268  
 269        $query = new PhabricatorPolicyAwareTestQuery();
 270        $query->setResults(array($object));
 271        $query->setViewer($viewer);
 272  
 273        $caught = null;
 274        try {
 275          $result = $query->executeOne();
 276        } catch (PhabricatorPolicyException $ex) {
 277          $caught = $ex;
 278        }
 279  
 280        if ($expect) {
 281          $this->assertEqual(
 282            $object,
 283            $result,
 284            "{$description} with user {$spec} should succeed.");
 285        } else {
 286          $this->assertTrue(
 287            $caught instanceof PhabricatorPolicyException,
 288            "{$description} with user {$spec} should fail.");
 289        }
 290      }
 291    }
 292  
 293  
 294    /**
 295     * Build a test object to spec.
 296     */
 297    private function buildObject($policy) {
 298      $object = new PhabricatorPolicyTestObject();
 299      $object->setCapabilities(
 300        array(
 301          PhabricatorPolicyCapability::CAN_VIEW,
 302        ));
 303      $object->setPolicies(
 304        array(
 305          PhabricatorPolicyCapability::CAN_VIEW => $policy,
 306        ));
 307  
 308      return $object;
 309    }
 310  
 311  
 312    /**
 313     * Build a test user to spec.
 314     */
 315    private function buildUser($spec) {
 316      $user = new PhabricatorUser();
 317  
 318      switch ($spec) {
 319        case 'public':
 320          break;
 321        case 'user':
 322          $user->setPHID(1);
 323          break;
 324        case 'admin':
 325          $user->setPHID(1);
 326          $user->setIsAdmin(true);
 327          break;
 328        default:
 329          throw new Exception("Unknown user spec '{$spec}'.");
 330      }
 331  
 332      return $user;
 333    }
 334  
 335  }


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