<?php /** * 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\Tracker; use Piwik\EventDispatcher; use Piwik\Piwik; use Piwik\Plugins\CustomVariables\CustomVariables; use Piwik\Plugins\UsersManager\API; use Piwik\Plugins\UsersManager\Model; use Piwik\Plugins\UsersManager\UsersManager; use Piwik\Tests\Framework\Fixture; use Piwik\Tracker\Cache; use Piwik\Tracker\Request; use Piwik\Tests\Framework\TestCase\IntegrationTestCase; use Piwik\Tracker\TrackerConfig; class TestRequest extends Request { public function setIsAuthenticated() { $this->isAuthenticated = true; } } /** * @group RequestTest * @group Request * @group Tracker */ class RequestTest extends IntegrationTestCase { /** * @var TestRequest */ private $request; public function setUp() { parent::setUp(); Fixture::createWebsite('2014-01-01 00:00:00'); Fixture::createWebsite('2014-01-01 00:00:00'); Cache::deleteTrackerCache(); $this->request = $this->buildRequest(array('idsite' => '1')); } public function tearDown() { EventDispatcher::getInstance()->clearObservers('Request.initAuthenticationObject'); parent::tearDown(); } public function test_getCustomVariablesInVisitScope_ShouldReturnNoCustomVars_IfNoWerePassedInParams() { $this->assertEquals(array(), $this->request->getCustomVariablesInVisitScope()); } public function test_getCustomVariablesInVisitScope_ShouldReturnNoCustomVars_IfPassedParamIsNotAnArray() { $this->assertCustomVariablesInVisitScope(array(), '{"mykey":"myval"}'); } public function test_getCustomVariablesInVisitScope_ShouldReturnCustomVars_IfTheyAreValid() { $customVars = $this->buildCustomVars(array('mykey' => 'myval', 'test' => 'value')); $expected = $this->buildExpectedCustomVars(array('mykey' => 'myval', 'test' => 'value')); $this->assertCustomVariablesInVisitScope($expected, $customVars); } public function test_getCustomVariablesInVisitScope_ShouldIgnoreIndexesLowerThan1() { $customVars = array( array('mykey', 'myval'), array('test', 'value'), ); $expected = $this->buildExpectedCustomVars(array('test' => 'value')); $this->assertCustomVariablesInVisitScope($expected, json_encode($customVars)); } public function test_getCustomVariablesInVisitScope_ShouldTruncateValuesIfTheyAreTooLong() { $maxLen = CustomVariables::getMaxLengthCustomVariables(); $customVars = $this->buildCustomVars(array( 'mykey' => 'myval', 'test' => str_pad('test', $maxLen + 5, 't'), )); $expected = $this->buildExpectedCustomVars(array( 'mykey' => 'myval', 'test' => str_pad('test', $maxLen, 't'), )); $this->assertCustomVariablesInVisitScope($expected, $customVars); } public function test_getCustomVariablesInVisitScope_ShouldIgnoreVarsThatDoNotHaveKeyAndValue() { $customVars = array( 1 => array('mykey', 'myval'), 2 => array('test'), ); $expected = $this->buildExpectedCustomVars(array('mykey' => 'myval')); $this->assertCustomVariablesInVisitScope($expected, json_encode($customVars)); } public function test_getCustomVariablesInVisitScope_ShouldSetDefaultValueToEmptyStringAndHandleOtherTypes() { $input = array( 'myfloat' => 5.55, 'myint' => 53, 'mystring' => '', ); $customVars = $this->buildCustomVars($input); $expected = $this->buildExpectedCustomVars($input); $this->assertCustomVariablesInVisitScope($expected, $customVars); } public function test_getCustomVariablesInPageScope_ShouldReturnNoCustomVars_IfNoWerePassedInParams() { $this->assertEquals(array(), $this->request->getCustomVariablesInPageScope()); } public function test_getCustomVariablesInPageScope_ShouldReturnNoCustomVars_IfPassedParamIsNotAnArray() { $this->assertCustomVariablesInPageScope(array(), '{"mykey":"myval"}'); } public function test_getCustomVariablesInPageScope_ShouldReturnCustomVars_IfTheyAreValid() { $customVars = $this->buildCustomVars(array('mykey' => 'myval', 'test' => 'value')); $expected = $this->buildExpectedCustomVars(array('mykey' => 'myval', 'test' => 'value')); $this->assertCustomVariablesInPageScope($expected, $customVars); } public function test_getCustomVariablesInPageScope_ShouldIgnoreIndexesLowerThan1() { $customVars = array( array('mykey', 'myval'), array('test', 'value'), ); $expected = $this->buildExpectedCustomVars(array('test' => 'value')); $this->assertCustomVariablesInPageScope($expected, json_encode($customVars)); } public function test_getCustomVariablesInPageScope_ShouldTruncateValuesIfTheyAreTooLong() { $maxLen = CustomVariables::getMaxLengthCustomVariables(); $customVars = $this->buildCustomVars(array( 'mykey' => 'myval', 'test' => str_pad('test', $maxLen + 5, 't'), )); $expected = $this->buildExpectedCustomVars(array( 'mykey' => 'myval', 'test' => str_pad('test', $maxLen, 't'), )); $this->assertCustomVariablesInPageScope($expected, $customVars); } public function test_getCustomVariablesInPageScope_ShouldIgnoreVarsThatDoNotHaveKeyAndValue() { $customVars = array( 1 => array('mykey', 'myval'), 2 => array('test'), ); $expected = $this->buildExpectedCustomVars(array('mykey' => 'myval')); $this->assertCustomVariablesInPageScope($expected, json_encode($customVars)); } public function test_getCustomVariablesInPageScope_ShouldSetDefaultValueToEmptyStringAndHandleOtherTypes() { $input = array( 'myfloat' => 5.55, 'myint' => 53, 'mystring' => '', ); $customVars = $this->buildCustomVars($input); $expected = $this->buildExpectedCustomVars($input); $this->assertCustomVariablesInPageScope($expected, $customVars); } public function test_isAuthenticated_ShouldBeNotAuthenticatedInTestsByDefault() { $this->assertFalse($this->request->isAuthenticated()); } public function test_isAuthenticated_ShouldBeAuthenticatedIfCheckIsDisabledInConfig() { $oldConfig = TrackerConfig::getConfigValue('tracking_requests_require_authentication'); TrackerConfig::setConfigValue('tracking_requests_require_authentication', 0); $this->assertTrue($this->request->isAuthenticated()); TrackerConfig::setConfigValue('tracking_requests_require_authentication', $oldConfig); } public function test_isAuthenticated_ShouldReadTheIsAuthenticatedPropertyAndIgnoreACheck() { $this->assertFalse($this->request->isAuthenticated()); $this->request->setIsAuthenticated(); $this->assertTrue($this->request->isAuthenticated()); } public function test_isAuthenticated_ShouldWorkIfTokenIsCorrect() { $token = $this->createAdminUserForSite(2); $request = $this->buildRequestWithToken(array('idsite' => '1'), $token); $this->assertFalse($request->isAuthenticated()); $request = $this->buildRequestWithToken(array('idsite' => '2'), $token); $this->assertTrue($request->isAuthenticated()); } public function test_isAuthenticated_ShouldAlwaysWorkForSuperUser() { Fixture::createSuperUser(false); $token = Fixture::getTokenAuth(); $request = $this->buildRequestWithToken(array('idsite' => '1'), $token); $this->assertTrue($request->isAuthenticated()); $request = $this->buildRequestWithToken(array('idsite' => '2'), $token); $this->assertTrue($request->isAuthenticated()); } public function test_authenticateSuperUserOrAdmin_ShouldFailIfTokenIsEmpty() { $isAuthenticated = Request::authenticateSuperUserOrAdmin('', 2); $this->assertFalse($isAuthenticated); $isAuthenticated = Request::authenticateSuperUserOrAdmin(null, 2); $this->assertFalse($isAuthenticated); } public function test_authenticateSuperUserOrAdmin_ShouldPostAuthInitEvent_IfTokenIsGiven() { $called = 0; Piwik::addAction('Request.initAuthenticationObject', function () use (&$called) { $called++; }); Request::authenticateSuperUserOrAdmin('', 2); $this->assertSame(0, $called); Request::authenticateSuperUserOrAdmin('atoken', 2); $this->assertSame(1, $called); Request::authenticateSuperUserOrAdmin('anothertoken', 2); $this->assertSame(2, $called); Request::authenticateSuperUserOrAdmin(null, 2); $this->assertSame(2, $called); } public function test_authenticateSuperUserOrAdmin_ShouldNotBeAllowedToAccessSitesHavingInvalidId() { $token = $this->createAdminUserForSite(2); $isAuthenticated = Request::authenticateSuperUserOrAdmin($token, -2); $this->assertFalse($isAuthenticated); $isAuthenticated = Request::authenticateSuperUserOrAdmin($token, 0); $this->assertFalse($isAuthenticated); } public function test_authenticateSuperUserOrAdmin_ShouldWorkIfTokenIsCorrect() { $token = $this->createAdminUserForSite(2); $isAuthenticated = Request::authenticateSuperUserOrAdmin($token, 1); $this->assertFalse($isAuthenticated); $isAuthenticated = Request::authenticateSuperUserOrAdmin($token, 2); $this->assertTrue($isAuthenticated); } public function test_authenticateSuperUserOrAdmin_ShouldAlwaysWorkForSuperUser() { Fixture::createSuperUser(false); $token = Fixture::getTokenAuth(); $isAuthenticated = Request::authenticateSuperUserOrAdmin($token, 1); $this->assertTrue($isAuthenticated); $isAuthenticated = Request::authenticateSuperUserOrAdmin($token, 2); $this->assertTrue($isAuthenticated); } private function createAdminUserForSite($idSite) { $login = 'myadmin'; $passwordHash = UsersManager::getPasswordHash('password'); $token = API::getInstance()->getTokenAuth($login, $passwordHash); $user = new Model(); $user->addUser($login, $passwordHash, 'admin@piwik', 'alias', $token, '2014-01-01 00:00:00'); $user->addUserAccess($login, 'admin', array($idSite)); return $token; } public function test_internalBuildExpectedCustomVars() { $this->assertEquals(array(), $this->buildExpectedCustomVars(array())); $this->assertEquals(array('custom_var_k1' => 'key', 'custom_var_v1' => 'val'), $this->buildExpectedCustomVars(array('key' => 'val'))); $this->assertEquals(array( 'custom_var_k1' => 'key', 'custom_var_v1' => 'val', 'custom_var_k2' => 'key2', 'custom_var_v2' => 'val2', ), $this->buildExpectedCustomVars(array('key' => 'val', 'key2' => 'val2'))); } public function test_internalBuildCustomVars() { $this->assertEquals('[]', $this->buildCustomVars(array())); $this->assertEquals('{"1":["key","val"]}', $this->buildCustomVars(array('key' => 'val'))); $this->assertEquals('{"1":["key","val"],"2":["key2","val2"]}', $this->buildCustomVars(array('key' => 'val', 'key2' => 'val2'))); } private function assertCustomVariablesInVisitScope($expectedCvars, $cvarsJsonEncoded) { $request = $this->buildRequest(array('_cvar' => $cvarsJsonEncoded)); $this->assertEquals($expectedCvars, $request->getCustomVariablesInVisitScope()); } private function assertCustomVariablesInPageScope($expectedCvars, $cvarsJsonEncoded) { $request = $this->buildRequest(array('cvar' => $cvarsJsonEncoded)); $this->assertEquals($expectedCvars, $request->getCustomVariablesInPageScope()); } private function buildExpectedCustomVars($customVars) { $vars = array(); $index = 1; foreach ($customVars as $key => $value) { $vars['custom_var_k' . $index] = $key; $vars['custom_var_v' . $index] = $value; $index++; } return $vars; } private function buildCustomVars($customVars) { $vars = array(); $index = 1; foreach ($customVars as $key => $value) { $vars[$index] = array($key, $value); $index++; } return json_encode($vars); } private function buildRequest($params) { return new TestRequest($params); } private function buildRequestWithToken($params, $token) { return new TestRequest($params, $token); } }