diff --git a/Slack.php b/Slack.php index 4461f43..a428055 100644 --- a/Slack.php +++ b/Slack.php @@ -116,6 +116,12 @@ public function validateReportParameters(&$parameters, $reportType) } elseif (empty($parameters[self::SLACK_CHANNEL_ID_PARAMETER])) { throw new \Exception(Piwik::translate('Slack_SlackChannelIdRequiredErrorMessage')); } + $slackChannels = explode(',', (string) $parameters[self::SLACK_CHANNEL_ID_PARAMETER]); + foreach ($slackChannels as $slackChannel) { + if (!ctype_alnum($slackChannel)) { + throw new \Exception(Piwik::translate('Slack_SlackChannelIdInvalidErrorMessage')); + } + } } /** @@ -384,8 +390,15 @@ public function uninstall() */ public function validateCustomAlertReportParameters($parameters, $alertMedium) { - if ($alertMedium === self::SLACK_TYPE && empty($parameters[self::SLACK_CHANNEL_ID_PARAMETER])) { - throw new \Exception(Piwik::translate('Slack_SlackChannelIdRequiredErrorMessage')); + if ($alertMedium === self::SLACK_TYPE) { + $settings = StaticContainer::get(SystemSettings::class); + if (empty($settings->slackOauthToken->getValue())) { + throw new \Exception(Piwik::translate('Slack_OauthTokenRequiredErrorMessage')); + } elseif (empty($parameters[self::SLACK_CHANNEL_ID_PARAMETER])) { + throw new \Exception(Piwik::translate('Slack_SlackChannelIdRequiredErrorMessage')); + } elseif (!ctype_alnum($parameters[self::SLACK_CHANNEL_ID_PARAMETER])) { + throw new \Exception(Piwik::translate('Slack_SlackChannelIdInvalidErrorMessage')); + } } } diff --git a/lang/en.json b/lang/en.json index f3e19b0..5d1c6dc 100644 --- a/lang/en.json +++ b/lang/en.json @@ -7,6 +7,7 @@ "OauthTokenSettingDescription": "Enter your Slack OAuth Token generated from your Slack. %1$sLearn more%2$s.", "PleaseFindYourReport": "Here is your %1$s report for %2$s", "SlackChannelIdRequiredErrorMessage": "Slack Channel ID cannot be empty.", + "SlackChannelIdInvalidErrorMessage": "Invalid Slack Channel ID, only alphanumeric values are allowed.", "SlackChannel": "Slack Channel", "SlackEnterYourSlackChannelIdHelpText": "Enter the Slack Channel ID of the channel that will receive these reports. To find the ID, go to Slack and open the channel details > About tab. %1$sLearn more%2$s", "SlackAlertContent": "%1$s has been triggered for website %2$s as the metric %3$s in report %4$s %5$s." diff --git a/tests/Integration/CustomAlertsApiTest.php b/tests/Integration/CustomAlertsApiTest.php index 19acdec..312c72f 100644 --- a/tests/Integration/CustomAlertsApiTest.php +++ b/tests/Integration/CustomAlertsApiTest.php @@ -9,6 +9,8 @@ namespace Piwik\Plugins\Slack\tests; +use Piwik\Container\StaticContainer; +use Piwik\Plugins\Slack\SystemSettings; use Piwik\Tests\Framework\Fixture; use Piwik\Tests\Framework\TestCase\IntegrationTestCase; use Piwik\Tests\Framework\TestingEnvironmentManipulator; @@ -43,6 +45,20 @@ public function setUp(): void $this->idSite = Fixture::createWebsite('2012-08-09 11:22:33'); } + public function testAddAlertShouldThrowExceptionIfSlackOauthTokenNotSet() + { + $this->expectException(\Exception::class); + $this->expectExceptionMessage('Slack_OauthTokenRequiredErrorMessage'); + $this->addAlert('', false); + } + + public function testAddAlertShouldThrowExceptionIfSlackChannelIdNotEmptyButOauthTokenNotSet() + { + $this->expectException(\Exception::class); + $this->expectExceptionMessage('Slack_OauthTokenRequiredErrorMessage'); + $this->addAlert('channelID', false); + } + public function testAddAlertShouldThrowExceptionIfEmptySlackChannelId() { $this->expectException(\Exception::class); @@ -50,6 +66,20 @@ public function testAddAlertShouldThrowExceptionIfEmptySlackChannelId() $this->addAlert(); } + public function testAddAlertShouldThrowExceptionIfInvalidSlackChannelId() + { + $this->expectException(\Exception::class); + $this->expectExceptionMessage('Slack_SlackChannelIdInvalidErrorMessage'); + $this->addAlert('ChanneldId1@123'); + } + + public function testAddAlertShouldThrowExceptionIfInvalidSlackChannelId2() + { + $this->expectException(\Exception::class); + $this->expectExceptionMessage('Slack_SlackChannelIdInvalidErrorMessage'); + $this->addAlert('ChannelID1,ChannelID2'); + } + public function testAddAlertSuccess() { $id = $this->addAlert($slackChannelId = 'channelID'); @@ -76,8 +106,13 @@ public function testUpdateAlertSuccess() $this->assertEquals('channelIDNew', $alert['slack_channel_id']); } - private function addAlert($slackChannelId = '') + private function addAlert($slackChannelId = '', $createToken = true) { + if ($createToken) { + $settings = StaticContainer::get(SystemSettings::class); + $settings->slackOauthToken->setValue('test123'); + } + return $this->api->addAlert( 'Test Slack and Email', $this->idSite, diff --git a/tests/Integration/SlackTest.php b/tests/Integration/SlackTest.php index 95258c3..c949d43 100644 --- a/tests/Integration/SlackTest.php +++ b/tests/Integration/SlackTest.php @@ -10,6 +10,7 @@ namespace Piwik\Plugins\Slack\tests; use Piwik\Container\StaticContainer; +use Piwik\Piwik; use Piwik\Plugins\ScheduledReports\API; use Piwik\Plugins\ScheduledReports\ScheduledReports; use Piwik\Plugins\Slack\Slack; @@ -113,6 +114,72 @@ public function getAlertData() ]; } + public function testValidateReportParametersSlackTokenNotSetShouldThrowOauthException() + { + $this->expectException(\Exception::class); + $this->expectExceptionMessage('Slack_OauthTokenRequiredErrorMessage'); + $parameters = [ScheduledReports::DISPLAY_FORMAT_PARAMETER => ScheduledReports::DISPLAY_FORMAT_GRAPHS_ONLY]; + Piwik::postEvent('ScheduledReports.validateReportParameters', [&$parameters, 'slack']); + } + + public function testValidateReportParametersSlackTokenNotSetShouldThrowSlackChannelIdEmptyException() + { + $settings = StaticContainer::get(SystemSettings::class); + $settings->slackOauthToken->setValue('test123'); + $this->expectException(\Exception::class); + $this->expectExceptionMessage('Slack_SlackChannelIdRequiredErrorMessage'); + $parameters = [ScheduledReports::DISPLAY_FORMAT_PARAMETER => ScheduledReports::DISPLAY_FORMAT_GRAPHS_ONLY]; + Piwik::postEvent('ScheduledReports.validateReportParameters', [&$parameters, 'slack']); + } + + public function testValidateReportParametersSlackTokenNotSetShouldThrowSlackChannelIdEmptyException2() + { + $settings = StaticContainer::get(SystemSettings::class); + $settings->slackOauthToken->setValue('test123'); + $this->expectException(\Exception::class); + $this->expectExceptionMessage('Slack_SlackChannelIdRequiredErrorMessage'); + $parameters = [ScheduledReports::DISPLAY_FORMAT_PARAMETER => ScheduledReports::DISPLAY_FORMAT_GRAPHS_ONLY, Slack::SLACK_CHANNEL_ID_PARAMETER => '']; + Piwik::postEvent('ScheduledReports.validateReportParameters', [&$parameters, 'slack']); + } + + public function testValidateReportParametersSlackTokenNotSetShouldThrowSlackChannelIdInvalidException() + { + $settings = StaticContainer::get(SystemSettings::class); + $settings->slackOauthToken->setValue('test123'); + $this->expectException(\Exception::class); + $this->expectExceptionMessage('Slack_SlackChannelIdInvalidErrorMessage'); + $parameters = [ScheduledReports::DISPLAY_FORMAT_PARAMETER => ScheduledReports::DISPLAY_FORMAT_GRAPHS_ONLY, Slack::SLACK_CHANNEL_ID_PARAMETER => 'test123@11']; + Piwik::postEvent('ScheduledReports.validateReportParameters', [&$parameters, 'slack']); + } + + public function testValidateReportParametersSlackTokenNotSetShouldThrowSlackChannelIdInvalidException2() + { + $settings = StaticContainer::get(SystemSettings::class); + $settings->slackOauthToken->setValue('test123'); + $this->expectException(\Exception::class); + $this->expectExceptionMessage('Slack_SlackChannelIdInvalidErrorMessage'); + $parameters = [ScheduledReports::DISPLAY_FORMAT_PARAMETER => ScheduledReports::DISPLAY_FORMAT_GRAPHS_ONLY, Slack::SLACK_CHANNEL_ID_PARAMETER => 'test123,Demo@11']; + Piwik::postEvent('ScheduledReports.validateReportParameters', [&$parameters, 'slack']); + } + + public function testValidateReportParametersSlackTokenShouldNotThrowAnyException() + { + $settings = StaticContainer::get(SystemSettings::class); + $settings->slackOauthToken->setValue('test123'); + $parameters = [ScheduledReports::DISPLAY_FORMAT_PARAMETER => ScheduledReports::DISPLAY_FORMAT_GRAPHS_ONLY, Slack::SLACK_CHANNEL_ID_PARAMETER => 'test123']; + Piwik::postEvent('ScheduledReports.validateReportParameters', [&$parameters, 'slack']); + $this->assertNotEmpty($parameters); + } + + public function testValidateReportParametersSlackTokenShouldNotThrowAnyException2() + { + $settings = StaticContainer::get(SystemSettings::class); + $settings->slackOauthToken->setValue('test123'); + $parameters = [ScheduledReports::DISPLAY_FORMAT_PARAMETER => ScheduledReports::DISPLAY_FORMAT_GRAPHS_ONLY, Slack::SLACK_CHANNEL_ID_PARAMETER => 'test123,dEmoA,abcd123']; + Piwik::postEvent('ScheduledReports.validateReportParameters', [&$parameters, 'slack']); + $this->assertNotEmpty($parameters); + } + private function assertHasReport($login, $idSite) { $report = $this->getReport($login, $idSite);