Skip to content
Extraits de code Groupes Projets
AccessTest.php 15,9 ko
Newer Older
  • Learn to ignore specific revisions
  •  * Piwik - free/libre analytics platform
    
     *
     * @link http://piwik.org
     * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
     */
    
    
    namespace Piwik\Tests\Integration;
    
    use Exception;
    
    use Piwik\Access;
    use Piwik\AuthResult;
    
    use Piwik\Db;
    use Piwik\NoAccessException;
    
    use Piwik\Tests\Framework\TestCase\IntegrationTestCase;
    
    class AccessTest extends IntegrationTestCase
    
            $accessList = Access::getListAccess();
    
            $shouldBe = array('noaccess', 'view', 'admin', 'superuser');
    
            $this->assertEquals($shouldBe, $accessList);
        }
    
        public function testGetTokenAuthWithEmptyAccess()
        {
    
            $access = new Access();
    
            $this->assertNull($access->getTokenAuth());
        }
    
        public function testGetLoginWithEmptyAccess()
        {
    
            $access = new Access();
    
        public function testHasSuperUserAccessWithEmptyAccess()
    
            $access = new Access();
    
            $this->assertFalse($access->hasSuperUserAccess());
    
        public function testHasSuperUserAccessWithSuperUserAccess()
    
            $this->assertTrue($access->hasSuperUserAccess());
    
        public function test_GetLogin_UserIsNotAnonymous_WhenSuperUserAccess()
        {
    
            $access->setSuperUserAccess(true);
            $this->assertNotEmpty($access->getLogin());
            $this->assertNotSame('anonymous', $access->getLogin());
        }
    
    
        public function testHasSuperUserAccessWithNoSuperUserAccess()
    
            $this->assertFalse($access->hasSuperUserAccess());
    
        }
    
        public function testGetSitesIdWithAtLeastViewAccessWithEmptyAccess()
        {
    
            $access = new Access();
    
            $this->assertEmpty($access->getSitesIdWithAtLeastViewAccess());
        }
    
        public function testGetSitesIdWithAdminAccessWithEmptyAccess()
        {
    
            $access = new Access();
    
            $this->assertEmpty($access->getSitesIdWithAdminAccess());
        }
    
        public function testGetSitesIdWithViewAccessWithEmptyAccess()
        {
    
            $access = new Access();
    
            $this->assertEmpty($access->getSitesIdWithViewAccess());
        }
    
        /**
    
         * @expectedException \Piwik\NoAccessException
    
        public function testCheckUserHasSuperUserAccessWithEmptyAccess()
    
            $access = new Access();
    
            $access->checkUserHasSuperUserAccess();
    
        public function testCheckUserHasSuperUserAccessWithSuperUserAccess()
    
            $access->checkUserHasSuperUserAccess();
    
         * @expectedException \Piwik\NoAccessException
    
         */
        public function testCheckUserHasSomeAdminAccessWithEmptyAccess()
        {
    
            $access = new Access();
    
            $access->checkUserHasSomeAdminAccess();
        }
    
        public function testCheckUserHasSomeAdminAccessWithSuperUserAccess()
        {
    
        /**
         * @expectedException \Piwik\NoAccessException
         */
        public function test_CheckUserHasSomeAdminAccessWithSomeAccessFails_IfUserHasPermissionsToSitesButIsNotAuthenticated()
        {
            $mock = $this->createAccessMockWithAccessToSitesButUnauthenticated(array(2, 9));
            $mock->checkUserHasSomeAdminAccess();
        }
    
        /**
         * @expectedException \Piwik\NoAccessException
         */
        public function test_checkUserHasAdminAccessFails_IfUserHasPermissionsToSitesButIsNotAuthenticated()
        {
            $mock = $this->createAccessMockWithAccessToSitesButUnauthenticated(array(2, 9));
            $mock->checkUserHasAdminAccess('2');
        }
    
        /**
         * @expectedException \Piwik\NoAccessException
         */
        public function test_checkUserHasSomeViewAccessFails_IfUserHasPermissionsToSitesButIsNotAuthenticated()
        {
            $mock = $this->createAccessMockWithAccessToSitesButUnauthenticated(array(2, 9));
            $mock->checkUserHasSomeViewAccess();
        }
    
        /**
         * @expectedException \Piwik\NoAccessException
         */
        public function test_checkUserHasViewAccessFails_IfUserHasPermissionsToSitesButIsNotAuthenticated()
        {
            $mock = $this->createAccessMockWithAccessToSitesButUnauthenticated(array(2, 9));
            $mock->checkUserHasViewAccess('2');
        }
    
    
        public function testCheckUserHasSomeAdminAccessWithSomeAccess()
        {
    
            $mock = $this->createAccessMockWithAuthenticatedUser(array('getRawSitesWithSomeViewAccess'));
    
                 ->method('getRawSitesWithSomeViewAccess')
                 ->will($this->returnValue($this->buildAdminAccessForSiteIds(array(2, 9))));
    
         * @expectedException \Piwik\NoAccessException
    
         */
        public function testCheckUserHasSomeViewAccessWithEmptyAccess()
        {
    
            $access = new Access();
    
            $access->checkUserHasSomeViewAccess();
        }
    
        public function testCheckUserHasSomeViewAccessWithSuperUserAccess()
        {
    
            $access->checkUserHasSomeViewAccess();
        }
    
        public function testCheckUserHasSomeViewAccessWithSomeAccess()
        {
    
            $mock = $this->createAccessMockWithAuthenticatedUser(array('getRawSitesWithSomeViewAccess'));
    
                ->method('getRawSitesWithSomeViewAccess')
                ->will($this->returnValue($this->buildViewAccessForSiteIds(array(1, 2, 3, 4))));
    
         * @expectedException \Piwik\NoAccessException
    
         */
        public function testCheckUserHasViewAccessWithEmptyAccessNoSiteIdsGiven()
        {
    
            $access = new Access();
    
            $access->checkUserHasViewAccess(array());
        }
    
        public function testCheckUserHasViewAccessWithSuperUserAccess()
        {
    
            $access = Access::getInstance();
    
            $access->checkUserHasViewAccess(array());
        }
    
        public function testCheckUserHasViewAccessWithSomeAccessSuccessIdSitesAsString()
        {
    
            /** @var Access $mock */
            $mock = $this->createAccessMockWithAuthenticatedUser(array('getRawSitesWithSomeViewAccess'));
    
                ->method('getRawSitesWithSomeViewAccess')
                ->will($this->returnValue($this->buildViewAccessForSiteIds(array(1, 2, 3, 4))));
    
    
            $mock->checkUserHasViewAccess('1,3');
        }
    
        public function testCheckUserHasViewAccessWithSomeAccessSuccessAllSites()
        {
    
            /** @var Access $mock */
            $mock = $this->createAccessMockWithAuthenticatedUser(array('getRawSitesWithSomeViewAccess'));
    
                ->method('getRawSitesWithSomeViewAccess')
                ->will($this->returnValue($this->buildViewAccessForSiteIds(array(1, 2, 3, 4))));
    
         * @expectedException \Piwik\NoAccessException
    
         */
        public function testCheckUserHasViewAccessWithSomeAccessFailure()
        {
            $mock = $this->getMock(
    
                array('getSitesIdWithAtLeastViewAccess')
    
                ->method('getSitesIdWithAtLeastViewAccess')
                ->will($this->returnValue(array(1, 2, 3, 4)));
    
    
            $mock->checkUserHasViewAccess(array(1, 5));
        }
    
        public function testCheckUserHasAdminAccessWithSuperUserAccess()
        {
    
         * @expectedException \Piwik\NoAccessException
    
         */
        public function testCheckUserHasAdminAccessWithEmptyAccessNoSiteIdsGiven()
        {
    
            $access = new Access();
    
            $access->checkUserHasViewAccess(array());
        }
    
        public function testCheckUserHasAdminAccessWithSomeAccessSuccessIdSitesAsString()
        {
            $mock = $this->getMock(
    
                ->method('getSitesIdWithAdminAccess')
                ->will($this->returnValue(array(1, 2, 3, 4)));
    
    
            $mock->checkUserHasAdminAccess('1,3');
        }
    
        public function testCheckUserHasAdminAccessWithSomeAccessSuccessAllSites()
        {
            $mock = $this->getMock(
    
                array('getSitesIdWithAdminAccess', 'getSitesIdWithAtLeastViewAccess')
    
                ->method('getSitesIdWithAdminAccess')
                ->will($this->returnValue(array(1, 2, 3, 4)));
    
                ->method('getSitesIdWithAtLeastViewAccess')
                ->will($this->returnValue(array(1, 2, 3, 4)));
    
         * @expectedException \Piwik\NoAccessException
    
         */
        public function testCheckUserHasAdminAccessWithSomeAccessFailure()
        {
            $mock = $this->getMock(
    
                ->method('getSitesIdWithAdminAccess')
                ->will($this->returnValue(array(1, 2, 3, 4)));
    
    
            $mock->checkUserHasAdminAccess(array(1, 5));
        }
    
        public function testReloadAccessWithEmptyAuth()
        {
    
            $access = new Access();
    
            $this->assertFalse($access->reloadAccess(null));
        }
    
        public function testReloadAccessWithEmptyAuthSuperUser()
        {
    
            $this->assertTrue($access->reloadAccess(null));
        }
    
    
        public function testReloadAccess_ShouldResetTokenAuthAndLogin_IfAuthIsNotValid()
        {
            $mock = $this->createAuthMockWithAuthResult(AuthResult::SUCCESS);
    
    
            $this->assertTrue($access->reloadAccess($mock));
            $this->assertSame('login', $access->getLogin());
            $this->assertSame('token', $access->getTokenAuth());
    
            $mock = $this->createAuthMockWithAuthResult(AuthResult::FAILURE);
    
            $this->assertFalse($access->reloadAccess($mock));
            $this->assertNull($access->getLogin());
            $this->assertNull($access->getTokenAuth());
        }
    
    
        public function testReloadAccessWithMockedAuthValid()
        {
    
            $mock = $this->createPiwikAuthMockInstance();
    
                ->will($this->returnValue(new AuthResult(AuthResult::SUCCESS, 'login', 'token')));
    
            $mock->expects($this->any())->method('getName')->will($this->returnValue("test name"));
    
    
            $this->assertTrue($access->reloadAccess($mock));
    
            $this->assertFalse($access->hasSuperUserAccess());
    
        public function test_reloadAccess_loadSitesIfNeeded_doesActuallyResetAllSiteIdsAndRequestThemAgain()
        {
            /** @var Access $mock */
            $mock = $this->createAccessMockWithAuthenticatedUser(array('getRawSitesWithSomeViewAccess'));
    
            $mock->expects($this->at(0))
                ->method('getRawSitesWithSomeViewAccess')
                ->will($this->returnValue($this->buildAdminAccessForSiteIds(array(1,2,3,4))));
    
            $mock->expects($this->at(1))
                ->method('getRawSitesWithSomeViewAccess')
                ->will($this->returnValue($this->buildAdminAccessForSiteIds(array(1))));
    
            // should succeed as permission to 1,2,3,4
            $mock->checkUserHasAdminAccess('1,3');
    
            // should clear permissions
            $mock->reloadAccess();
    
            try {
                // should fail as now only permission to site 1
                $mock->checkUserHasAdminAccess('1,3');
                $this->fail('An expected exception has not been triggered. Permissions were not resetted');
            } catch (NoAccessException $e) {
    
            }
    
            $mock->checkUserHasAdminAccess('1'); // it should have access to site "1"
    
            $mock->setSuperUserAccess(true);
    
            $mock->reloadAccess();
    
            // should now have permission as it is a superuser
            $mock->checkUserHasAdminAccess('1,3');
        }
    
    
        public function test_doAsSuperUser_ChangesSuperUserAccessCorrectly()
        {
            Access::getInstance()->setSuperUserAccess(false);
    
            $this->assertFalse(Access::getInstance()->hasSuperUserAccess());
    
            Access::doAsSuperUser(function () {
    
    Matthieu Napoli's avatar
    Matthieu Napoli a validé
                AccessTest::assertTrue(Access::getInstance()->hasSuperUserAccess());
    
            });
    
            $this->assertFalse(Access::getInstance()->hasSuperUserAccess());
        }
    
        public function test_doAsSuperUser_RemovesSuperUserAccess_IfExceptionThrown()
        {
            Access::getInstance()->setSuperUserAccess(false);
    
            $this->assertFalse(Access::getInstance()->hasSuperUserAccess());
    
            try {
                Access::doAsSuperUser(function () {
                    throw new Exception();
                });
    
                $this->fail("Exception was not propagated by doAsSuperUser.");
            } catch (Exception $ex)
            {
                // pass
            }
    
            $this->assertFalse(Access::getInstance()->hasSuperUserAccess());
        }
    
        public function test_doAsSuperUser_ReturnsCallbackResult()
        {
            $result = Access::doAsSuperUser(function () {
                return 24;
            });
            $this->assertEquals(24, $result);
        }
    
        public function test_reloadAccess_DoesNotRemoveSuperUserAccess_IfUsedInDoAsSuperUser()
        {
            Access::getInstance()->setSuperUserAccess(false);
    
            Access::doAsSuperUser(function () {
                $access = Access::getInstance();
    
    
    Matthieu Napoli's avatar
    Matthieu Napoli a validé
                AccessTest::assertTrue($access->hasSuperUserAccess());
    
                $access->reloadAccess();
    
    Matthieu Napoli's avatar
    Matthieu Napoli a validé
                AccessTest::assertTrue($access->hasSuperUserAccess());
    
    
        private function buildAdminAccessForSiteIds($siteIds)
        {
            $access = array();
    
            foreach ($siteIds as $siteId) {
                $access[] = array('access' => 'admin', 'idsite' => $siteId);
            }
    
            return $access;
        }
    
        private function buildViewAccessForSiteIds($siteIds)
        {
            $access = array();
    
            foreach ($siteIds as $siteId) {
                $access[] = array('access' => 'admin', 'idsite' => $siteId);
            }
    
            return $access;
        }
    
        private function createPiwikAuthMockInstance()
        {
            return $this->getMock('Piwik\\Auth', array('authenticate', 'getName', 'getTokenAuthSecret', 'getLogin', 'setTokenAuth', 'setLogin',
                'setPassword', 'setPasswordHash'));
        }
    
        private function createAccessMockWithAccessToSitesButUnauthenticated($idSites)
        {
            $mock = $this->getMock('Piwik\Access', array('getRawSitesWithSomeViewAccess', 'loadSitesIfNeeded'));
    
            // this method will be actually never called as it is unauthenticated. The tests are supposed to fail if it
            // suddenly does get called as we should not query for sites if it is not authenticated.
            $mock->expects($this->any())
                ->method('getRawSitesWithSomeViewAccess')
                ->will($this->returnValue($this->buildAdminAccessForSiteIds($idSites)));
    
            return $mock;
        }
    
        private function createAccessMockWithAuthenticatedUser($methodsToMock = array())
        {
            $methods = array('authenticate');
    
            foreach ($methodsToMock as $methodToMock) {
                $methods[] = $methodToMock;
            }
    
            $authMock = $this->createPiwikAuthMockInstance();
            $authMock->expects($this->atLeast(1))
                ->method('authenticate')
                ->will($this->returnValue(new AuthResult(AuthResult::SUCCESS, 'login', 'token')));
    
            $mock = $this->getMock('Piwik\Access', $methods);
            $mock->reloadAccess($authMock);
    
            return $mock;
        }
    
    
        private function createAuthMockWithAuthResult($resultCode)
        {
            $mock = $this->createPiwikAuthMockInstance();
            $mock->expects($this->once())
                ->method('authenticate')
                ->will($this->returnValue(new AuthResult($resultCode, 'login', 'token')));
    
            return $mock;
        }