diff --git a/src/applications/base/controller/__tests__/PhabricatorAccessControlTestCase.php b/src/applications/base/controller/__tests__/PhabricatorAccessControlTestCase.php index 560e0c95c4..27e716556e 100644 --- a/src/applications/base/controller/__tests__/PhabricatorAccessControlTestCase.php +++ b/src/applications/base/controller/__tests__/PhabricatorAccessControlTestCase.php @@ -1,281 +1,280 @@ true, ); } public function testControllerAccessControls() { $root = dirname(phutil_get_library_root('phabricator')); require_once $root.'/support/PhabricatorStartup.php'; $application_configuration = new AphrontDefaultApplicationConfiguration(); $host = 'meow.example.com'; $_SERVER['REQUEST_METHOD'] = 'GET'; $request = id(new AphrontRequest($host, '/')) ->setApplicationConfiguration($application_configuration) ->setRequestData(array()); $controller = new PhabricatorTestController(); $controller->setRequest($request); $u_public = id(new PhabricatorUser()) ->setUsername('public'); $u_unverified = $this->generateNewTestUser() ->setUsername('unverified') ->save(); $u_unverified->setIsEmailVerified(0)->save(); $u_normal = $this->generateNewTestUser() ->setUsername('normal') ->save(); $u_disabled = $this->generateNewTestUser() ->setIsDisabled(true) ->setUsername('disabled') ->save(); $u_admin = $this->generateNewTestUser() ->setIsAdmin(true) ->setUsername('admin') ->save(); $u_notapproved = $this->generateNewTestUser() ->setIsApproved(0) ->setUsername('notapproved') ->save(); $env = PhabricatorEnv::beginScopedEnv(); $env->overrideEnvConfig('phabricator.base-uri', 'http://'.$host); $env->overrideEnvConfig('policy.allow-public', false); $env->overrideEnvConfig('auth.require-email-verification', false); - $env->overrideEnvConfig('auth.email-domains', array()); $env->overrideEnvConfig('security.require-multi-factor-auth', false); // Test standard defaults. $this->checkAccess( pht('Default'), id(clone $controller), $request, array( $u_normal, $u_admin, $u_unverified, ), array( $u_public, $u_disabled, $u_notapproved, )); // Test email verification. $env->overrideEnvConfig('auth.require-email-verification', true); $this->checkAccess( pht('Email Verification Required'), id(clone $controller), $request, array( $u_normal, $u_admin, ), array( $u_unverified, $u_public, $u_disabled, $u_notapproved, )); $this->checkAccess( pht('Email Verification Required, With Exception'), id(clone $controller)->setConfig('email', false), $request, array( $u_normal, $u_admin, $u_unverified, ), array( $u_public, $u_disabled, $u_notapproved, )); $env->overrideEnvConfig('auth.require-email-verification', false); // Test admin access. $this->checkAccess( pht('Admin Required'), id(clone $controller)->setConfig('admin', true), $request, array( $u_admin, ), array( $u_normal, $u_unverified, $u_public, $u_disabled, $u_notapproved, )); // Test disabled access. $this->checkAccess( pht('Allow Disabled'), id(clone $controller)->setConfig('enabled', false), $request, array( $u_normal, $u_unverified, $u_admin, $u_disabled, $u_notapproved, ), array( $u_public, )); // Test no login required. $this->checkAccess( pht('No Login Required'), id(clone $controller)->setConfig('login', false), $request, array( $u_normal, $u_unverified, $u_admin, $u_public, ), array( $u_disabled, $u_notapproved, )); // Test public access. $this->checkAccess( pht('Public Access'), id(clone $controller)->setConfig('public', true), $request, array( $u_normal, $u_unverified, $u_admin, ), array( $u_disabled, $u_public, )); $env->overrideEnvConfig('policy.allow-public', true); $this->checkAccess( pht('Public + configured'), id(clone $controller)->setConfig('public', true), $request, array( $u_normal, $u_unverified, $u_admin, $u_public, ), array( $u_disabled, $u_notapproved, )); $env->overrideEnvConfig('policy.allow-public', false); $app = PhabricatorApplication::getByClass('PhabricatorTestApplication'); $app->reset(); $app->setPolicy( PhabricatorPolicyCapability::CAN_VIEW, PhabricatorPolicies::POLICY_NOONE); $app_controller = id(clone $controller)->setCurrentApplication($app); $this->checkAccess( pht('Application Controller'), $app_controller, $request, array( ), array( $u_normal, $u_unverified, $u_admin, $u_public, $u_disabled, $u_notapproved, )); $this->checkAccess( pht('Application Controller'), id(clone $app_controller)->setConfig('login', false), $request, array( $u_normal, $u_unverified, $u_admin, $u_public, ), array( $u_disabled, $u_notapproved, )); } private function checkAccess( $label, $controller, $request, array $yes, array $no) { foreach ($yes as $user) { $request->setUser($user); $uname = $user->getUsername(); try { $result = id(clone $controller)->willBeginExecution(); } catch (Exception $ex) { $result = $ex; } $this->assertTrue( ($result === null), pht("Expect user '%s' to be allowed access to '%s'.", $uname, $label)); } foreach ($no as $user) { $request->setUser($user); $uname = $user->getUsername(); try { $result = id(clone $controller)->willBeginExecution(); } catch (Exception $ex) { $result = $ex; } $this->assertFalse( ($result === null), pht("Expect user '%s' to be denied access to '%s'.", $uname, $label)); } } } diff --git a/src/infrastructure/testing/PhabricatorTestCase.php b/src/infrastructure/testing/PhabricatorTestCase.php index 32fe4f3bee..068c2ed557 100644 --- a/src/infrastructure/testing/PhabricatorTestCase.php +++ b/src/infrastructure/testing/PhabricatorTestCase.php @@ -1,229 +1,233 @@ getPhabricatorTestCaseConfiguration() + array( self::PHABRICATOR_TESTCONFIG_ISOLATE_LISK => true, self::PHABRICATOR_TESTCONFIG_BUILD_STORAGE_FIXTURES => false, ); if ($config[self::PHABRICATOR_TESTCONFIG_BUILD_STORAGE_FIXTURES]) { // Fixtures don't make sense with process isolation. $config[self::PHABRICATOR_TESTCONFIG_ISOLATE_LISK] = false; } return $config; } public function willRunTestCases(array $test_cases) { $root = dirname(phutil_get_library_root('phabricator')); require_once $root.'/scripts/__init_script__.php'; $config = $this->getComputedConfiguration(); if ($config[self::PHABRICATOR_TESTCONFIG_BUILD_STORAGE_FIXTURES]) { ++self::$storageFixtureReferences; if (!self::$storageFixture) { self::$storageFixture = $this->newStorageFixture(); } } ++self::$testsAreRunning; } public function didRunTestCases(array $test_cases) { if (self::$storageFixture) { self::$storageFixtureReferences--; if (!self::$storageFixtureReferences) { self::$storageFixture = null; } } --self::$testsAreRunning; } protected function willRunTests() { $config = $this->getComputedConfiguration(); if ($config[self::PHABRICATOR_TESTCONFIG_ISOLATE_LISK]) { LiskDAO::beginIsolateAllLiskEffectsToCurrentProcess(); } $this->env = PhabricatorEnv::beginScopedEnv(); // NOTE: While running unit tests, we act as though all applications are // installed, regardless of the install's configuration. Tests which need // to uninstall applications are responsible for adjusting state themselves // (such tests are exceedingly rare). $this->env->overrideEnvConfig( 'phabricator.uninstalled-applications', array()); $this->env->overrideEnvConfig( 'phabricator.show-prototypes', true); // Reset application settings to defaults, particularly policies. $this->env->overrideEnvConfig( 'phabricator.application-settings', array()); // We can't stub this service right now, and it's not generally useful // to publish notifications about test execution. $this->env->overrideEnvConfig( 'notification.enabled', false); $this->env->overrideEnvConfig( 'phabricator.base-uri', 'http://phabricator.example.com'); + $this->env->overrideEnvConfig( + 'auth.email-domains', + array()); + // Tests do their own stubbing/voiding for events. $this->env->overrideEnvConfig('phabricator.silent', false); } protected function didRunTests() { $config = $this->getComputedConfiguration(); if ($config[self::PHABRICATOR_TESTCONFIG_ISOLATE_LISK]) { LiskDAO::endIsolateAllLiskEffectsToCurrentProcess(); } try { if (phutil_is_hiphop_runtime()) { $this->env->__destruct(); } unset($this->env); } catch (Exception $ex) { throw new Exception( pht( 'Some test called %s, but is still holding '. 'a reference to the scoped environment!', 'PhabricatorEnv::beginScopedEnv()')); } } protected function willRunOneTest($test) { $config = $this->getComputedConfiguration(); if ($config[self::PHABRICATOR_TESTCONFIG_BUILD_STORAGE_FIXTURES]) { LiskDAO::beginIsolateAllLiskEffectsToTransactions(); } } protected function didRunOneTest($test) { $config = $this->getComputedConfiguration(); if ($config[self::PHABRICATOR_TESTCONFIG_BUILD_STORAGE_FIXTURES]) { LiskDAO::endIsolateAllLiskEffectsToTransactions(); } } protected function newStorageFixture() { $bytes = Filesystem::readRandomCharacters(24); $name = self::NAMESPACE_PREFIX.$bytes; return new PhabricatorStorageFixtureScopeGuard($name); } /** * Returns an integer seed to use when building unique identifiers (e.g., * non-colliding usernames). The seed is unstable and its value will change * between test runs, so your tests must not rely on it. * * @return int A unique integer. */ protected function getNextObjectSeed() { self::$storageFixtureObjectSeed += mt_rand(1, 100); return self::$storageFixtureObjectSeed; } protected function generateNewTestUser() { $seed = $this->getNextObjectSeed(); $user = id(new PhabricatorUser()) ->setRealName(pht('Test User %s', $seed)) ->setUserName("test{$seed}") ->setIsApproved(1); $email = id(new PhabricatorUserEmail()) ->setAddress("testuser{$seed}@example.com") ->setIsVerified(1); $editor = new PhabricatorUserEditor(); $editor->setActor($user); $editor->createNewUser($user, $email); return $user; } /** * Throws unless tests are currently executing. This method can be used to * guard code which is specific to unit tests and should not normally be * reachable. * * If tests aren't currently being executed, throws an exception. */ public static function assertExecutingUnitTests() { if (!self::$testsAreRunning) { throw new Exception( pht( 'Executing test code outside of test execution! '. 'This code path can only be run during unit tests.')); } } protected function requireBinaryForTest($binary) { if (!Filesystem::binaryExists($binary)) { $this->assertSkipped( pht( 'No binary "%s" found on this system, skipping test.', $binary)); } } }