[FEATURE] Make indexed_search ready for GDPR 85/56785/2
authorGeorg Ringer <georg.ringer@gmail.com>
Mon, 16 Apr 2018 08:46:57 +0000 (10:46 +0200)
committerGeorg Ringer <georg.ringer@gmail.com>
Tue, 24 Apr 2018 00:02:58 +0000 (02:02 +0200)
To be compatible with the GDPR, 2 new features are added to
the indexed_search extension:

- Make the index_stat_search table part of the garbage collector task
- Make the IP tracking configurable

Resolves: #84740
Releases: master, 8.7, 7.6
Change-Id: I8e1bcd937a3d4095fb1a048064e82845ff1a5344
Reviewed-on: https://review.typo3.org/56737
Tested-by: TYPO3com <no-reply@typo3.com>
Reviewed-by: Frank Naegler <frank.naegler@typo3.org>
Tested-by: Frank Naegler <frank.naegler@typo3.org>
Reviewed-on: https://review.typo3.org/56785
Reviewed-by: Georg Ringer <georg.ringer@gmail.com>
Tested-by: Georg Ringer <georg.ringer@gmail.com>
typo3/sysext/core/Documentation/Changelog/7.6.x/Feature-84740-MakeIndexed_searchReadyForGDPR.rst [new file with mode: 0644]
typo3/sysext/indexed_search/Classes/Controller/SearchController.php
typo3/sysext/indexed_search/Classes/Controller/SearchFormController.php
typo3/sysext/indexed_search/Resources/Private/Language/locallang_em.xlf
typo3/sysext/indexed_search/composer.json
typo3/sysext/indexed_search/ext_conf_template.txt
typo3/sysext/indexed_search/ext_emconf.php
typo3/sysext/indexed_search/ext_localconf.php

diff --git a/typo3/sysext/core/Documentation/Changelog/7.6.x/Feature-84740-MakeIndexed_searchReadyForGDPR.rst b/typo3/sysext/core/Documentation/Changelog/7.6.x/Feature-84740-MakeIndexed_searchReadyForGDPR.rst
new file mode 100644 (file)
index 0000000..358a459
--- /dev/null
@@ -0,0 +1,32 @@
+.. include:: ../../Includes.txt
+
+====================================================
+Feature: #84740 - Make indexed_search ready for GDPR
+====================================================
+
+See :issue:`84740`
+
+Description
+===========
+
+The following features have been added to the extension `indexed_search` to make it compatible with the GDPR law:
+
+**Add table `index_stat_search` to the available garbage collector tasks**
+
+Entries of the table `index_stat_search` can now be deleted after a given amount of days by using
+the scheduler task *Table garbage collection* of the extension `scheduler`.
+
+**Make the IP tracking configurable**
+
+Every successful search is tracked in the table `index_stat_search` which includes the IP address of the client as well.
+The :php:`\TYPO3\CMS\Core\Utility\IpAnonymizationUtility` is now used to mask the IP.
+The level of privacy can be configured in the extension configuration in the Install Tool with
+the setting `trackIpInStatistic`. By default it is set to `2`, which means that the host and subnet are masked.
+
+
+Impact
+======
+
+Configure your installation as needed. Define the tracking of the IP address and the removal of not needed search statistics.
+
+.. index:: ext:indexed_search
\ No newline at end of file
index c0f702e..1392452 100644 (file)
@@ -16,6 +16,7 @@ namespace TYPO3\CMS\IndexedSearch\Controller;
 
 use TYPO3\CMS\Core\Html\HtmlParser;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Core\Utility\IpAnonymizationUtility;
 use TYPO3\CMS\Core\Utility\MathUtility;
 use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
 
@@ -758,6 +759,13 @@ class SearchController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionControlle
      */
     protected function writeSearchStat($searchParams, $searchWords, $count, $pt)
     {
+        $ipAddress = '';
+        try {
+            $ipMask = isset($this->indexerConfig['trackIpInStatistic']) ? (int)$this->indexerConfig['trackIpInStatistic'] : 2;
+            $ipAddress = IpAnonymizationUtility::anonymizeIp(GeneralUtility::getIndpEnv('REMOTE_ADDR'), $ipMask);
+        } catch (\Exception $e) {
+        }
+
         $insertFields = [
             'searchstring' => $this->sword,
             'searchoptions' => serialize([$searchParams, $searchWords, $pt]),
@@ -765,7 +773,7 @@ class SearchController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionControlle
             // cookie as set or retrieved. If people has cookies disabled this will vary all the time
             'cookie' => $GLOBALS['TSFE']->fe_user->id,
             // Remote IP address
-            'IP' => GeneralUtility::getIndpEnv('REMOTE_ADDR'),
+            'IP' => $ipAddress,
             // Number of hits on the search
             'hits' => (int)$count,
             // Time stamp
index 598ca52..a167ca8 100644 (file)
@@ -16,6 +16,7 @@ namespace TYPO3\CMS\IndexedSearch\Controller;
 
 use TYPO3\CMS\Core\Html\HtmlParser;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Core\Utility\IpAnonymizationUtility;
 use TYPO3\CMS\Core\Utility\MathUtility;
 use TYPO3\CMS\IndexedSearch\Utility;
 
@@ -1309,6 +1310,13 @@ class SearchFormController extends \TYPO3\CMS\Frontend\Plugin\AbstractPlugin
      */
     public function writeSearchStat($sWArr, $count, $pt)
     {
+        $ipAddress = '';
+        try {
+            $ipMask = isset($this->indexerConfig['trackIpInStatistic']) ? (int)$this->indexerConfig['trackIpInStatistic'] : 2;
+            $ipAddress = IpAnonymizationUtility::anonymizeIp(GeneralUtility::getIndpEnv('REMOTE_ADDR'), $ipMask);
+        } catch (\Exception $e) {
+        }
+
         $insertFields = [
             'searchstring' => $this->piVars['sword'],
             'searchoptions' => serialize([$this->piVars, $sWArr, $pt]),
@@ -1316,7 +1324,7 @@ class SearchFormController extends \TYPO3\CMS\Frontend\Plugin\AbstractPlugin
             // fe_user id, integer
             'cookie' => (string)$GLOBALS['TSFE']->id,
             // cookie as set or retrieve. If people has cookies disabled this will vary all the time...
-            'IP' => GeneralUtility::getIndpEnv('REMOTE_ADDR'),
+            'IP' => $ipAddress,
             // Remote IP address
             'hits' => (int)$count,
             // Number of hits on the search.
index d2f1734..e946a3a 100644 (file)
@@ -57,6 +57,9 @@
                        <trans-unit id="indexedsearch.config.indexExternalURLs">
                                <source>Index External HTML URLs: If set, links to external URLs will be indexed if they are of type "text/html".</source>
                        </trans-unit>
+                       <trans-unit id="indexedsearch.config.trackIpInStatistic">
+                               <source>Define the privacy level of the logged IP: 0 for no mask which means no privacy, 1 for masking the host and 2 for masking host and subnet (full privacy)</source>
+                       </trans-unit>
                </body>
        </file>
 </xliff>
index e848b48..fd67688 100644 (file)
@@ -11,6 +11,9 @@
        "replace": {
                "indexed_search": "*"
        },
+       "suggest": {
+               "typo3/cms-scheduler": "For garbage collection of search statistics"
+       },
        "autoload": {
                "psr-4": {
                        "TYPO3\\CMS\\IndexedSearch\\": "Classes/"
index b93e160..699e706 100644 (file)
@@ -19,6 +19,9 @@ ppthtml = /usr/bin/
   # cat=basic; type=string; label=LLL:EXT:indexed_search/Resources/Private/Language/locallang_em.xlf:indexedsearch.config.unrtf
 unrtf = /usr/bin/
 
+# cat=basic; type=int; label=LLL:EXT:indexed_search/Resources/Private/Language/locallang_em.xlf:indexedsearch.config.trackIpInStatistic
+trackIpInStatistic = 2
+
    # cat=basic; type=boolean; label=LLL:EXT:indexed_search/Resources/Private/Language/locallang_em.xlf:indexedsearch.config.debugMode
 debugMode = 0
 
index fcb076a..6a289d6 100644 (file)
@@ -16,6 +16,8 @@ $EM_CONF[$_EXTKEY] = [
             'typo3' => '7.6.28',
         ],
         'conflicts' => [],
-        'suggests' => [],
+        'suggests' => [
+            'scheduler' => '',
+        ],
     ],
 ];
index b0b2ac0..274d841 100644 (file)
@@ -68,3 +68,10 @@ $_EXTCONF = unserialize($_EXTCONF);
 if (isset($_EXTCONF['enableMetaphoneSearch']) && (int)$_EXTCONF['enableMetaphoneSearch'] == 2) {
     $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['indexed_search']['metaphone'] = \TYPO3\CMS\IndexedSearch\Utility\DoubleMetaPhoneUtility::class;
 }
+
+if (isset($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['scheduler']['tasks'][\TYPO3\CMS\Scheduler\Task\TableGarbageCollectionTask::class]['options']['tables'])) {
+    $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['scheduler']['tasks'][\TYPO3\CMS\Scheduler\Task\TableGarbageCollectionTask::class]['options']['tables']['index_stat_search'] = [
+        'dateField' => 'tstamp',
+        'expirePeriod' => 90
+    ];
+}