Skip to content

Commit 44d2c99

Browse files
authored
Add third party cookie check for CNIL (#23820)
* Update config getter trait to support site specific config * Add third party cookie settings + tests * Hook up TrackerConfig to ThirdPartyConfig
1 parent 13cc726 commit 44d2c99

15 files changed

+361
-11
lines changed

core/Policy/PolicyManager.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
use Piwik\Settings\Plugin\SystemConfigSetting;
2626
use Piwik\Settings\Plugin\SystemSetting;
2727
use Piwik\Settings\Setting;
28+
use Piwik\Tracker\Config\ThirdPartyCookies;
2829

2930
class PolicyManager
3031
{
@@ -103,6 +104,9 @@ protected static function getAllSettings(?string $settingType = null): array
103104
$settings = Manager::getInstance()->findMultipleComponents('Settings', SettingValueInterface::class);
104105
$underPolicy = [];
105106

107+
// Add core specific settings
108+
$settings[] = ThirdPartyCookies::class;
109+
106110
foreach ($settings as $setting) {
107111
if (!is_a($setting, PolicyComparisonInterface::class, true)) {
108112
continue;

core/Settings/Interfaces/ConfigSettingInterface.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,5 @@ interface ConfigSettingInterface
1717
/**
1818
* @return T
1919
*/
20-
public static function getConfigValue();
20+
public static function getConfigValue(int $idSite = null);
2121
}

core/Settings/Interfaces/Traits/Getters/ConfigGetterTrait.php

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,15 @@ trait ConfigGetterTrait
2222
/**
2323
* @return T|null
2424
*/
25-
public static function getConfigValue()
25+
public static function getConfigValue(int $idSite = null)
2626
{
27-
$config = Config::getInstance()->{self::getConfigSection()};
27+
$configKey = self::getConfigSection();
28+
29+
if ($idSite !== null) {
30+
$configKey .= '_' . $idSite;
31+
}
32+
33+
$config = Config::getInstance()->{$configKey};
2834

2935
if (is_null($config) || !array_key_exists(self::getConfigSettingName(), $config)) {
3036
return null;
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
<?php
2+
3+
namespace Piwik\Tracker\Config;
4+
5+
use Piwik\Piwik;
6+
use Piwik\Settings\Interfaces\ConfigSettingInterface;
7+
use Piwik\Settings\Interfaces\PolicyComparisonInterface;
8+
use Piwik\Settings\Interfaces\SettingValueInterface;
9+
use Piwik\Settings\Interfaces\Traits\PolicyComparisonTrait;
10+
use Piwik\Settings\Interfaces\Traits\Getters\ConfigGetterTrait;
11+
use Piwik\Policy\CnilPolicy;
12+
13+
/**
14+
* @implements ConfigSettingInterface<bool|null>
15+
* @implements PolicyComparisonInterface<bool|null>
16+
* @implements SettingValueInterface<bool|null>
17+
*/
18+
class ThirdPartyCookies implements
19+
ConfigSettingInterface,
20+
PolicyComparisonInterface,
21+
SettingValueInterface
22+
{
23+
/**
24+
* @use ConfigGetterTrait<bool|null>
25+
*/
26+
use ConfigGetterTrait;
27+
28+
/**
29+
* @use PolicyComparisonTrait<bool|null>
30+
*/
31+
use PolicyComparisonTrait;
32+
33+
/**
34+
* @var bool|null
35+
*/
36+
private $value;
37+
38+
private function __construct(?bool $value)
39+
{
40+
$this->value = $value;
41+
}
42+
43+
protected static function getConfigSection(): string
44+
{
45+
return 'Tracker';
46+
}
47+
48+
protected static function getConfigSettingName(): string
49+
{
50+
return 'use_third_party_id_cookie';
51+
}
52+
53+
public static function getPolicyRequirements(): array
54+
{
55+
return [
56+
CnilPolicy::class => false,
57+
];
58+
}
59+
60+
public static function isCompliant(string $policy, ?int $idSite = null): bool
61+
{
62+
$policyValues = self::getPolicyRequirements();
63+
64+
if (!array_key_exists($policy, $policyValues)) {
65+
return true;
66+
}
67+
68+
$currentValue = self::getInstance($idSite)->getValue();
69+
70+
return $currentValue === $policyValues[$policy];
71+
}
72+
73+
public static function getComplianceRequirementNote(?int $idSite = null): string
74+
{
75+
return Piwik::translate('General_ThirdPartyCookieSettingNote');
76+
}
77+
78+
protected static function compareStrictness($value1, $value2): bool
79+
{
80+
if ($value1 === true && $value2 === true) {
81+
return true;
82+
}
83+
return false;
84+
}
85+
86+
public static function getTitle(): string
87+
{
88+
return Piwik::translate('General_ThirdPartyCookieSettingTitle');
89+
}
90+
91+
public static function getInstance(?int $idSite = null): self
92+
{
93+
$values = self::getPolicyRequiredValues($idSite);
94+
$configValue = self::getConfigValue($idSite);
95+
96+
if ($configValue === null) {
97+
// Without site ID
98+
$configValue = self::getConfigValue();
99+
}
100+
$values['config'] = $configValue;
101+
$strictest = self::getStrictestValueFromArray($values);
102+
return new self($strictest);
103+
}
104+
105+
public function getValue()
106+
{
107+
return $this->value;
108+
}
109+
110+
public static function getInlineHelp(): string
111+
{
112+
return '';
113+
}
114+
}

core/Tracker/TrackerConfig.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@
1010
namespace Piwik\Tracker;
1111

1212
use Piwik\Config;
13+
use Piwik\Container\StaticContainer;
14+
use Piwik\Plugins\FeatureFlags\FeatureFlagManager;
15+
use Piwik\Plugins\PrivacyManager\FeatureFlags\PrivacyCompliance;
16+
use Piwik\Tracker\Config\ThirdPartyCookies;
1317

1418
class TrackerConfig
1519
{
@@ -28,6 +32,13 @@ public static function setConfigValue($name, $value)
2832

2933
public static function getConfigValue($name, $idSite = null)
3034
{
35+
if ($name === 'use_third_party_id_cookie') {
36+
$featureFlagManager = StaticContainer::get(FeatureFlagManager::class);
37+
if ($featureFlagManager->isFeatureActive(PrivacyCompliance::class)) {
38+
return ThirdPartyCookies::getInstance($idSite)->getValue();
39+
}
40+
}
41+
3142
$config = self::getConfig();
3243
if (!empty($idSite)) {
3344
$siteSpecificConfig = self::getSiteSpecificConfig($idSite);

lang/en.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,8 @@
473473
"Testing": "Testing…",
474474
"ThankYouForUsingMatomo": "Thank you for using Matomo",
475475
"TheMatomoTeam": "The Matomo Team",
476+
"ThirdPartyCookieSettingTitle": "Third party cookies",
477+
"ThirdPartyCookieSettingNote": "Third party cookies must be disabled",
476478
"TimeAgo": "%s ago",
477479
"TimeFormat": "Time format",
478480
"TimeOnPage": "Time on page",

plugins/PrivacyManager/tests/System/expected/test___PrivacyManager.getComplianceStatus.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,11 @@
6363
<value>non_compliant</value>
6464
<notes>Collection of User ID while tracking must be disabled.</notes>
6565
</row>
66+
<row>
67+
<name>Third party cookies</name>
68+
<value>compliant</value>
69+
<notes>Third party cookies must be disabled</notes>
70+
</row>
6671
<row>
6772
<name>Opt out</name>
6873
<value>unknown</value>

plugins/PrivacyManager/tests/System/expected/test_configControlledDisabled__PrivacyManager.getComplianceStatus.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,11 @@
6363
<value>non_compliant</value>
6464
<notes>Collection of User ID while tracking must be disabled.</notes>
6565
</row>
66+
<row>
67+
<name>Third party cookies</name>
68+
<value>compliant</value>
69+
<notes>Third party cookies must be disabled</notes>
70+
</row>
6671
<row>
6772
<name>Opt out</name>
6873
<value>unknown</value>

plugins/PrivacyManager/tests/System/expected/test_configControlledEnabled__PrivacyManager.getComplianceStatus.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,11 @@
6363
<value>compliant</value>
6464
<notes>Collection of User ID while tracking must be disabled.</notes>
6565
</row>
66+
<row>
67+
<name>Third party cookies</name>
68+
<value>compliant</value>
69+
<notes>Third party cookies must be disabled</notes>
70+
</row>
6671
<row>
6772
<name>Opt out</name>
6873
<value>unknown</value>
Lines changed: 2 additions & 2 deletions
Loading

0 commit comments

Comments
 (0)