diff --git a/core/Piwik.php b/core/Piwik.php index 625a7cf9f8f7024e819ac4c1b4786c95e9820515..80ed01cd8ca00edbb77a1321c630af2e148a1479 100644 --- a/core/Piwik.php +++ b/core/Piwik.php @@ -468,6 +468,7 @@ class Piwik * in case another Login plugin is being used. * * @return string + * @api */ public static function getLoginPluginName() { diff --git a/core/Updates/2.0.3-b7.php b/core/Updates/2.0.3-b7.php index add119e462cb16bcbe11f340ecc5bb73ae1033d1..9903d999c15d28dfd1a7c76565864edb56092313 100644 --- a/core/Updates/2.0.3-b7.php +++ b/core/Updates/2.0.3-b7.php @@ -23,9 +23,11 @@ class Updates_2_0_3_b7 extends Updates $errors = array(); try { + $checker = new DoNotTrackHeaderChecker(); + // enable DoNotTrack check in PrivacyManager if DoNotTrack plugin was enabled if (\Piwik\Plugin\Manager::getInstance()->isPluginActivated('DoNotTrack')) { - DoNotTrackHeaderChecker::activate(); + $checker->activate(); } // enable IP anonymization if AnonymizeIP plugin was enabled diff --git a/plugins/CoreAdminHome/Controller.php b/plugins/CoreAdminHome/Controller.php index af45ccc327f7e62d873cfa87f7cefe0c78da78bb..55452ad5dbc36e0d190280253c9abb8d0cb4c46b 100644 --- a/plugins/CoreAdminHome/Controller.php +++ b/plugins/CoreAdminHome/Controller.php @@ -22,6 +22,7 @@ use Piwik\Plugins\CorePluginsAdmin\UpdateCommunication; use Piwik\Plugins\CustomVariables\CustomVariables; use Piwik\Plugins\LanguagesManager\API as APILanguagesManager; use Piwik\Plugins\LanguagesManager\LanguagesManager; +use Piwik\Plugins\PrivacyManager\DoNotTrackHeaderChecker; use Piwik\Plugins\SitesManager\API as APISitesManager; use Piwik\Settings\Manager as SettingsManager; use Piwik\Site; @@ -235,7 +236,8 @@ class Controller extends \Piwik\Plugin\ControllerAdmin // get currencies for each viewable site $view->currencySymbols = APISitesManager::getInstance()->getCurrencySymbols(); - $view->serverSideDoNotTrackEnabled = \Piwik\Plugins\PrivacyManager\DoNotTrackHeaderChecker::isActive(); + $dntChecker = new DoNotTrackHeaderChecker(); + $view->serverSideDoNotTrackEnabled = $dntChecker->isActive(); return $view->render(); } diff --git a/plugins/PrivacyManager/Controller.php b/plugins/PrivacyManager/Controller.php index c950d789ed44814adc9b518473b3b6f250058aeb..1a50d7ac63daad31c805edfe3c65d4610e94447a 100644 --- a/plugins/PrivacyManager/Controller.php +++ b/plugins/PrivacyManager/Controller.php @@ -133,7 +133,8 @@ class Controller extends \Piwik\Plugin\ControllerAdmin if (Piwik::hasUserSuperUserAccess()) { $view->deleteData = $this->getDeleteDataInfo(); $view->anonymizeIP = $this->getAnonymizeIPInfo(); - $view->dntSupport = DoNotTrackHeaderChecker::isActive(); + $dntChecker = new DoNotTrackHeaderChecker(); + $view->dntSupport = $dntChecker->isActive(); $view->canDeleteLogActions = Db::isLockPrivilegeGranted(); $view->dbUser = PiwikConfig::getInstance()->database['username']; $view->deactivateNonce = Nonce::getNonce(self::DEACTIVATE_DNT_NONCE); @@ -297,7 +298,8 @@ class Controller extends \Piwik\Plugin\ControllerAdmin Piwik::checkUserHasSuperUserAccess(); Nonce::checkNonce(self::DEACTIVATE_DNT_NONCE); - DoNotTrackHeaderChecker::deactivate(); + $dntChecker = new DoNotTrackHeaderChecker(); + $dntChecker->deactivate(); $this->redirectToIndex('PrivacyManager', 'privacySettings'); } @@ -307,7 +309,8 @@ class Controller extends \Piwik\Plugin\ControllerAdmin Piwik::checkUserHasSuperUserAccess(); Nonce::checkNonce(self::ACTIVATE_DNT_NONCE); - DoNotTrackHeaderChecker::activate(); + $dntChecker = new DoNotTrackHeaderChecker(); + $dntChecker->activate(); $this->redirectToIndex('PrivacyManager', 'privacySettings'); } diff --git a/plugins/PrivacyManager/DoNotTrackHeaderChecker.php b/plugins/PrivacyManager/DoNotTrackHeaderChecker.php index 14938f426e4461c409a762a942255e127dc7a5f5..d5dd29658328b3f847aa373baef8ace436a1c775 100644 --- a/plugins/PrivacyManager/DoNotTrackHeaderChecker.php +++ b/plugins/PrivacyManager/DoNotTrackHeaderChecker.php @@ -18,9 +18,15 @@ use Piwik\Tracker\Request; * - X-Do-Not-Track header (used by AdBlockPlus and NoScript) * - DNT header (used by Mozilla) * + * Note: visits from Internet Explorer and other browsers that have DoNoTrack enabled by default will be tracked anyway. */ class DoNotTrackHeaderChecker { + public function __construct(Config $config = null) + { + $this->config = $config ?: new Config(); + } + /** * Checks for DoNotTrack headers and if found, sets `$exclude` to `true`. */ @@ -31,25 +37,9 @@ class DoNotTrackHeaderChecker return; } - if (!$this->isActive()) { - Common::printDebug("DoNotTrack support is not enabled, skip check"); - return; - } - - if ((isset($_SERVER['HTTP_X_DO_NOT_TRACK']) && $_SERVER['HTTP_X_DO_NOT_TRACK'] === '1') - || (isset($_SERVER['HTTP_DNT']) && substr($_SERVER['HTTP_DNT'], 0, 1) === '1') - ) { - $request = new Request($_REQUEST); - $ua = $request->getUserAgent(); - if (strpos($ua, 'MSIE') !== false - || strpos($ua, 'Trident') !== false) { - Common::printDebug("INTERNET EXPLORER enable DoNotTrack by default; so Piwik ignores DNT IE browsers..."); - return; - } - - Common::printDebug("DoNotTrack header found!"); + $exclude = $this->isDoNotTrackFound(); - $exclude = true; + if($exclude) { $trackingCookie = IgnoreCookie::getTrackingCookie(); $trackingCookie->delete(); @@ -58,27 +48,50 @@ class DoNotTrackHeaderChecker // /.well-known/dnt // per Tracking Preference Expression (draft) header('Tk: 1'); - } else { + } + } + + /** + * @return bool + */ + public function isDoNotTrackFound() + { + if (!$this->isActive()) { + Common::printDebug("DoNotTrack support is not enabled, skip check"); + return false; + } + + if (!$this->isHeaderDntFound()) { Common::printDebug("DoNotTrack header not found"); + return false; + } + + $request = new Request($_REQUEST); + $userAgent = $request->getUserAgent(); + + if ($this->isUserAgentExcludedFromDNT($userAgent)) { + Common::printDebug("INTERNET EXPLORER enable DoNotTrack by default; so Piwik ignores DNT IE browsers..."); + return false; } + + Common::printDebug("DoNotTrack header found!"); + return true; } /** * Deactivates DoNotTrack header checking. This function will not be called by the Tracker. */ - public static function deactivate() + public function deactivate() { - $config = new Config(); - $config->doNotTrackEnabled = false; + $this->config->doNotTrackEnabled = false; } /** * Activates DoNotTrack header checking. This function will not be called by the Tracker. */ - public static function activate() + public function activate() { - $config = new Config(); - $config->doNotTrackEnabled = true; + $this->config->doNotTrackEnabled = true; } /** @@ -86,9 +99,47 @@ class DoNotTrackHeaderChecker * * @return bool */ - public static function isActive() + public function isActive() + { + return $this->config->doNotTrackEnabled; + } + + /** + * @return bool + */ + protected function isHeaderDntFound() + { + return (isset($_SERVER['HTTP_X_DO_NOT_TRACK']) && $_SERVER['HTTP_X_DO_NOT_TRACK'] === '1') + || (isset($_SERVER['HTTP_DNT']) && substr($_SERVER['HTTP_DNT'], 0, 1) === '1'); + } + + /** + * + * @param $userAgent + * @return bool + */ + protected function isUserAgentExcludedFromDNT($userAgent) + { + $browsersWithDnt = $this->getBrowsersWithDNTAlwaysEnabled(); + foreach($browsersWithDnt as $userAgentBrowserFragment) { + if (strpos($userAgent, $userAgentBrowserFragment) !== false) { + return true; + } + } + return false; + } + + /** + * Some browsers have DNT enabled by default. For those we will ignore DNT and always track those users. + * + * @return array + */ + protected function getBrowsersWithDNTAlwaysEnabled() { - $config = new Config(); - return $config->doNotTrackEnabled; + return array( + // + 'MSIE', + 'Trident', + ); } } diff --git a/plugins/PrivacyManager/PrivacyManager.php b/plugins/PrivacyManager/PrivacyManager.php index ddce27fa3cd0c28ab1650995a32f7ea1033927e9..c803638a04760301a7ef68cc9d92130d6bd1ee1f 100644 --- a/plugins/PrivacyManager/PrivacyManager.php +++ b/plugins/PrivacyManager/PrivacyManager.php @@ -177,7 +177,7 @@ class PrivacyManager extends Plugin // default values $form->addDataSource(new HTML_QuickForm2_DataSource_Array(array( - 'do_not_track' => DoNotTrackHeaderChecker::isActive(), + 'do_not_track' => $this->dntChecker->isActive(), 'anonymise_ip' => IPAnonymizer::isActive(), ))); } @@ -190,10 +190,11 @@ class PrivacyManager extends Plugin public function installationFormSubmit(FormDefaultSettings $form) { $doNotTrack = (bool) $form->getSubmitValue('do_not_track'); + $dntChecker = new DoNotTrackHeaderChecker(); if ($doNotTrack) { - DoNotTrackHeaderChecker::activate(); + $dntChecker->activate(); } else { - DoNotTrackHeaderChecker::deactivate(); + $dntChecker->deactivate(); } $anonymiseIp = (bool) $form->getSubmitValue('anonymise_ip'); diff --git a/tests/PHPUnit/Framework/Fixture.php b/tests/PHPUnit/Framework/Fixture.php index ff5d6cc97a55ea4a324596793a11ff48657a3f53..f12e522c9a96ce18e96210d30535fcd3a1d1a571 100644 --- a/tests/PHPUnit/Framework/Fixture.php +++ b/tests/PHPUnit/Framework/Fixture.php @@ -227,7 +227,8 @@ class Fixture extends \PHPUnit_Framework_Assert if ($this->configureComponents) { IPAnonymizer::deactivate(); - DoNotTrackHeaderChecker::deactivate(); + $dntChecker = new DoNotTrackHeaderChecker(); + $dntChecker->deactivate(); } if ($this->createSuperUser) {