Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/matomo-org/matomo.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/Db/Schema/Mysql.php2
-rw-r--r--core/Notification/Manager.php26
-rw-r--r--core/Session.php19
-rw-r--r--core/Session/SaveHandler/DbTable.php2
-rw-r--r--core/Session/SessionAuth.php12
-rw-r--r--core/Updates/4.5.0-b1.php43
-rw-r--r--core/Version.php3
-rw-r--r--plugins/Monolog/Handler/WebNotificationHandler.php8
-rw-r--r--tests/PHPUnit/Framework/Fixture.php3
-rw-r--r--tests/PHPUnit/Integration/Session/SaveHandler/DbTableTest.php37
-rw-r--r--tests/PHPUnit/Unit/Notification/ManagerTest.php84
11 files changed, 226 insertions, 13 deletions
diff --git a/core/Db/Schema/Mysql.php b/core/Db/Schema/Mysql.php
index c7afaa6d87..940f694e70 100644
--- a/core/Db/Schema/Mysql.php
+++ b/core/Db/Schema/Mysql.php
@@ -275,7 +275,7 @@ class Mysql implements SchemaInterface
id VARCHAR( 191 ) NOT NULL,
modified INTEGER,
lifetime INTEGER,
- data TEXT,
+ data MEDIUMTEXT,
PRIMARY KEY ( id )
) ENGINE=$engine DEFAULT CHARSET=$charset
",
diff --git a/core/Notification/Manager.php b/core/Notification/Manager.php
index a621f27bfd..6e1924e873 100644
--- a/core/Notification/Manager.php
+++ b/core/Notification/Manager.php
@@ -18,6 +18,7 @@ use Piwik\Session\SessionNamespace;
*/
class Manager
{
+ const MAX_NOTIFICATIONS_IN_SESSION = 30;
/**
* @var SessionNamespace
*/
@@ -36,6 +37,8 @@ class Manager
* element ID. It can only contain alphanumeric characters (underscores can
* be used).
* @param Notification $notification The notification to post.
+ * @return bool true if the notification was added, false if it was ignored because there were too many
+ * pending ones.
* @api
*/
public static function notify($id, Notification $notification)
@@ -43,7 +46,7 @@ class Manager
self::checkId($id);
self::removeOldestNotificationsIfThereAreTooMany();
- self::addNotification($id, $notification);
+ return self::addNotification($id, $notification);
}
/**
@@ -103,7 +106,7 @@ class Manager
throw new \Exception('Notification ID is empty.');
}
- if (!preg_match('/^(\w)*$/', $id)) {
+ if (!preg_match('/^\w*$/', $id)) {
throw new \Exception('Invalid Notification ID given. Only word characters (AlNum + underscore) allowed.');
}
}
@@ -112,9 +115,15 @@ class Manager
{
self::saveNotificationAcrossUiRequestsIfNeeded($id, $notification);
+ if (count(self::$notifications) >= self::MAX_NOTIFICATIONS_IN_SESSION) {
+ return false;
+ }
+
// we store all kinda notifications here so in case the session is not enabled or disabled later there is still
// a chance it gets delivered to the UI during the same request.
self::$notifications[$id] = $notification;
+
+ return true;
}
private static function saveNotificationAcrossUiRequestsIfNeeded($id, Notification $notification)
@@ -133,7 +142,7 @@ class Manager
return;
}
- $maxNotificationsInSession = 30;
+ $maxNotificationsInSession = self::MAX_NOTIFICATIONS_IN_SESSION;
$session = static::getSession();
@@ -200,4 +209,15 @@ class Manager
return static::$session;
}
+
+ public static function cancelAllNotifications()
+ {
+ self::$notifications = [];
+ }
+
+ // for tests
+ public static function getPendingInMemoryNotifications()
+ {
+ return self::$notifications;
+ }
}
diff --git a/core/Session.php b/core/Session.php
index 4c09c3b6cb..641334676c 100644
--- a/core/Session.php
+++ b/core/Session.php
@@ -100,13 +100,7 @@ class Session extends Zend_Session
@ini_set('session.serialize_handler', 'php_serialize');
}
- $config = array(
- 'name' => Common::prefixTable(DbTable::TABLE_NAME),
- 'primary' => 'id',
- 'modifiedColumn' => 'modified',
- 'dataColumn' => 'data',
- 'lifetimeColumn' => 'lifetime',
- );
+ $config = self::getDbTableConfig();
$saveHandler = new DbTable($config);
if ($saveHandler) {
@@ -226,4 +220,15 @@ class Session extends Zend_Session
Common::sendHeader($headerStr);
return $headerStr;
}
+
+ public static function getDbTableConfig()
+ {
+ return array(
+ 'name' => Common::prefixTable(DbTable::TABLE_NAME),
+ 'primary' => 'id',
+ 'modifiedColumn' => 'modified',
+ 'dataColumn' => 'data',
+ 'lifetimeColumn' => 'lifetime',
+ );
+ }
}
diff --git a/core/Session/SaveHandler/DbTable.php b/core/Session/SaveHandler/DbTable.php
index 46012cc216..52bbeeb37f 100644
--- a/core/Session/SaveHandler/DbTable.php
+++ b/core/Session/SaveHandler/DbTable.php
@@ -23,6 +23,8 @@ use Zend_Session_SaveHandler_Interface;
*/
class DbTable implements Zend_Session_SaveHandler_Interface
{
+ public static $wasSessionToLargeToRead = false;
+
protected $config;
protected $maxLifetime;
diff --git a/core/Session/SessionAuth.php b/core/Session/SessionAuth.php
index 19e7e24e19..bff91c113e 100644
--- a/core/Session/SessionAuth.php
+++ b/core/Session/SessionAuth.php
@@ -13,10 +13,12 @@ use Piwik\Auth;
use Piwik\AuthResult;
use Piwik\Common;
use Piwik\Config;
+use Piwik\Container\StaticContainer;
use Piwik\Date;
use Piwik\Plugins\UsersManager\Model;
use Piwik\Plugins\UsersManager\Model as UsersModel;
use Piwik\Session;
+use Psr\Log\LoggerInterface;
/**
* Validates already authenticated sessions.
@@ -94,6 +96,8 @@ class SessionAuth implements Auth
$sessionFingerprint = new SessionFingerprint();
$userModel = $this->userModel;
+ $this->checkIfSessionFailedToRead();
+
if ($this->isExpiredSession($sessionFingerprint)) {
$sessionFingerprint->clear();
return $this->makeAuthFailure();
@@ -231,4 +235,12 @@ class SessionAuth implements Auth
$isExpired = Date::now()->getTimestampUTC() > $expirationTime;
return $isExpired;
}
+
+ private function checkIfSessionFailedToRead()
+ {
+ if (Session\SaveHandler\DbTable::$wasSessionToLargeToRead) {
+ StaticContainer::get(LoggerInterface::class)->warning(
+ "Too much data stored in the session so it could not be read properly. If you were logged out, this is why.");
+ }
+ }
}
diff --git a/core/Updates/4.5.0-b1.php b/core/Updates/4.5.0-b1.php
new file mode 100644
index 0000000000..e79ebe7107
--- /dev/null
+++ b/core/Updates/4.5.0-b1.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ * Matomo - free/libre analytics platform
+ *
+ * @link https://matomo.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ *
+ */
+
+namespace Piwik\Updates;
+
+use Piwik\Updater;
+use Piwik\Updates as PiwikUpdates;
+use Piwik\Updater\Migration;
+use Piwik\Updater\Migration\Factory as MigrationFactory;
+
+class Updates_4_5_0_b1 extends PiwikUpdates
+{
+
+ /**
+ * @var MigrationFactory
+ */
+ private $migration;
+
+ public function __construct(MigrationFactory $factory)
+ {
+ $this->migration = $factory;
+ }
+
+ public function getMigrations(Updater $updater)
+ {
+ $migration1 = $this->migration->db->changeColumnType('session', 'data', 'MEDIUMTEXT');
+
+ return [
+ $migration1,
+ ];
+ }
+
+ public function doUpdate(Updater $updater)
+ {
+ $updater->executeMigrations(__FILE__, $this->getMigrations($updater));
+ }
+}
diff --git a/core/Version.php b/core/Version.php
index 8c0ebd1d8d..cd40ab0d9e 100644
--- a/core/Version.php
+++ b/core/Version.php
@@ -20,7 +20,8 @@ final class Version
* The current Matomo version.
* @var string
*/
- const VERSION = '4.4.1';
+ const VERSION = '4.5.0-b1';
+
const MAJOR_VERSION = 4;
public function isStableVersion($version)
diff --git a/plugins/Monolog/Handler/WebNotificationHandler.php b/plugins/Monolog/Handler/WebNotificationHandler.php
index 0269282c9f..c365403590 100644
--- a/plugins/Monolog/Handler/WebNotificationHandler.php
+++ b/plugins/Monolog/Handler/WebNotificationHandler.php
@@ -20,6 +20,8 @@ use Zend_Session_Exception;
*/
class WebNotificationHandler extends AbstractProcessingHandler
{
+ const MAX_NOTIFICATION_MESSAGE_LENGTH = 512;
+
public function isHandling(array $record)
{
if (!empty($record['context']['ignoreInScreenWriter'])) {
@@ -46,7 +48,11 @@ class WebNotificationHandler extends AbstractProcessingHandler
break;
}
- $message = $record['level_name'] . ': ' . htmlentities($record['message'], ENT_COMPAT | ENT_HTML401, 'UTF-8');
+ $recordMessage = $record['message'];
+ $recordMessage = str_replace(PIWIK_INCLUDE_PATH, '', $recordMessage);
+ $recordMessage = substr($recordMessage, 0, self::MAX_NOTIFICATION_MESSAGE_LENGTH);
+
+ $message = $record['level_name'] . ': ' . htmlentities($recordMessage, ENT_COMPAT | ENT_HTML401, 'UTF-8');
$message .= $this->getLiteDebuggingInfo();
$notification = new Notification($message);
diff --git a/tests/PHPUnit/Framework/Fixture.php b/tests/PHPUnit/Framework/Fixture.php
index bb5e33a9bd..8050865eff 100644
--- a/tests/PHPUnit/Framework/Fixture.php
+++ b/tests/PHPUnit/Framework/Fixture.php
@@ -43,6 +43,7 @@ use Piwik\Plugins\UserCountry\LocationProvider;
use Piwik\Plugins\UsersManager\API as APIUsersManager;
use Piwik\Plugins\UsersManager\UsersManager;
use Piwik\ReportRenderer;
+use Piwik\Session\SaveHandler\DbTable;
use Piwik\SettingsPiwik;
use Piwik\SettingsServer;
use Piwik\Singleton;
@@ -392,6 +393,7 @@ class Fixture extends \PHPUnit\Framework\Assert
public static function clearInMemoryCaches($resetTranslations = true)
{
+ DbTable::$wasSessionToLargeToRead = false;
Date::$now = null;
FrontController::$requestId = null;
Cache::$cache = null;
@@ -411,6 +413,7 @@ class Fixture extends \PHPUnit\Framework\Assert
\Piwik\Plugins\ScheduledReports\API::$cache = array();
Singleton::clearAll();
PluginsArchiver::$archivers = array();
+ \Piwik\Notification\Manager::cancelAllNotifications();
Plugin\API::unsetAllInstances();
$_GET = $_REQUEST = array();
diff --git a/tests/PHPUnit/Integration/Session/SaveHandler/DbTableTest.php b/tests/PHPUnit/Integration/Session/SaveHandler/DbTableTest.php
new file mode 100644
index 0000000000..e71af20a32
--- /dev/null
+++ b/tests/PHPUnit/Integration/Session/SaveHandler/DbTableTest.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ * Matomo - free/libre analytics platform
+ *
+ * @link https://matomo.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ *
+ */
+
+namespace Piwik\Tests\Integration\Session\SaveHandler;
+
+use Piwik\Session;
+use Piwik\Session\SaveHandler\DbTable;
+use Piwik\Tests\Framework\TestCase\IntegrationTestCase;
+
+class DbTableTest extends IntegrationTestCase
+{
+ /**
+ * @var DbTable
+ */
+ private $testInstance;
+
+ public function setUp(): void
+ {
+ parent::setUp();
+ $this->testInstance = new DbTable(Session::getDbTableConfig());
+ }
+
+ public function test_read_returnsTheSessionDataCorrectly()
+ {
+ $this->testInstance->write('testid', 'testdata');
+
+ $result = $this->testInstance->read('testid');
+
+ $this->assertEquals('testdata', $result);
+ }
+} \ No newline at end of file
diff --git a/tests/PHPUnit/Unit/Notification/ManagerTest.php b/tests/PHPUnit/Unit/Notification/ManagerTest.php
new file mode 100644
index 0000000000..dd8673f1c0
--- /dev/null
+++ b/tests/PHPUnit/Unit/Notification/ManagerTest.php
@@ -0,0 +1,84 @@
+<?php
+/**
+ * Matomo - free/libre analytics platform
+ *
+ * @link https://matomo.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ *
+ */
+
+namespace Piwik\Tests\Unit\Notification;
+
+use PHPUnit\Framework\TestCase;
+use Piwik\Notification;
+use Piwik\Notification\Manager;
+
+class ManagerTest extends TestCase
+{
+ protected function setUp(): void
+ {
+ parent::setUp();
+
+ Manager::cancelAllNotifications();
+ }
+
+ protected function tearDown(): void
+ {
+ parent::tearDown();
+
+ Manager::cancelAllNotifications();
+ }
+
+ public function test_notify_addsNotificationToNotificationArray()
+ {
+ $notification = new Notification('abcdefg');
+ $result = Manager::notify('testid', $notification);
+
+ $this->assertTrue($result);
+
+ $notificationsInArray = Manager::getPendingInMemoryNotifications();
+
+ $expected = [
+ 'testid' => $notification,
+ ];
+ $this->assertEquals($expected, $notificationsInArray);
+ }
+
+ /**
+ * @dataProvider getTestDataForNotify
+ */
+ public function test_notify_throwsWhenAnInvalidIdIsUsed($id, $expectedMessage)
+ {
+ $this->expectException(\Exception::class);
+ $this->expectExceptionMessage($expectedMessage);
+
+ Manager::notify($id, new Notification('sldjfksdf'));
+ }
+
+ public function getTestDataForNotify()
+ {
+ return [
+ ['', 'Notification ID is empty.'],
+ ['aabcd a a k', 'Invalid Notification ID given. Only word characters (AlNum + underscore) allowed.'],
+ ['a23%$%', 'Invalid Notification ID given. Only word characters (AlNum + underscore) allowed.'],
+ ];
+ }
+
+ public function test_notify_doesNotAddNotificationIfThereAreAlreadyMoreThanThirty()
+ {
+ for ($i = 0; $i < Manager::MAX_NOTIFICATIONS_IN_SESSION; ++$i) {
+ Manager::notify('not' . $i, new Notification('message ' . $i));
+ }
+
+ $notificationsInArray = Manager::getPendingInMemoryNotifications();
+
+ $notification = new Notification('abcdefg');
+ $result = Manager::notify('testid', $notification);
+
+ $this->assertFalse($result);
+
+ $notificationsInArray = Manager::getPendingInMemoryNotifications();
+ $this->assertCount(30, $notificationsInArray);
+ $this->assertArrayNotHasKey('testid', $notificationsInArray);
+ }
+} \ No newline at end of file