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:
authordiosmosis <diosmosis@users.noreply.github.com>2019-03-08 01:42:03 +0300
committerGitHub <noreply@github.com>2019-03-08 01:42:03 +0300
commit0648513483a7c12eec6cc0aa55d49f87c061f6b0 (patch)
tree55e49065186371f8504c4dd9eb23df17f0a9c49c /plugins/UsersManager
parent7153700fe2e0ca4144854f60af2145457c3e00ce (diff)
Send email notification when user email changes. (#14136)
* Send email notification when user email changes. * Forgot to add file. * Apply pr fixes + send email for password changes too. * Add quick test for new emails. * Translate text * Refactor according to review. * ucfirst device name * Fixing integration test
Diffstat (limited to 'plugins/UsersManager')
-rw-r--r--plugins/UsersManager/API.php77
-rw-r--r--plugins/UsersManager/lang/en.json8
-rw-r--r--plugins/UsersManager/templates/_userInfoChangedEmail.twig14
-rw-r--r--plugins/UsersManager/tests/Integration/APITest.php13
4 files changed, 110 insertions, 2 deletions
diff --git a/plugins/UsersManager/API.php b/plugins/UsersManager/API.php
index be3ea0d103..dba779cb41 100644
--- a/plugins/UsersManager/API.php
+++ b/plugins/UsersManager/API.php
@@ -8,6 +8,7 @@
*/
namespace Piwik\Plugins\UsersManager;
+use DeviceDetector\DeviceDetector;
use Exception;
use Piwik\Access;
use Piwik\Access\CapabilitiesProvider;
@@ -17,6 +18,8 @@ use Piwik\Common;
use Piwik\Config;
use Piwik\Container\StaticContainer;
use Piwik\Date;
+use Piwik\IP;
+use Piwik\Mail;
use Piwik\Metrics\Formatter;
use Piwik\NoAccessException;
use Piwik\Option;
@@ -26,7 +29,7 @@ use Piwik\Plugins\Login\PasswordVerifier;
use Piwik\SettingsPiwik;
use Piwik\Site;
use Piwik\Tracker\Cache;
-use Piwik\Url;
+use Piwik\View;
/**
* The UsersManager API lets you Manage Users and their permissions to access specific websites.
@@ -915,6 +918,14 @@ class API extends \Piwik\Plugin\API
Cache::deleteTrackerCache();
+ if ($email != $userInfo['email']) {
+ $this->sendEmailChangedEmail($userInfo, $email);
+ }
+
+ if ($passwordHasBeenUpdated) {
+ $this->sendPasswordChangedEmail($userInfo);
+ }
+
/**
* Triggered after an existing user has been updated.
* Event notify about password change.
@@ -1379,4 +1390,68 @@ class API extends \Piwik\Plugin\API
}
return [$roles, $capabilities];
}
+
+ private function sendEmailChangedEmail($user, $newEmail)
+ {
+ // send the mail to both the old email and the new email
+ foreach ([$newEmail, $user['email']] as $emailTo) {
+ $this->sendUserInfoChangedEmail('email', $user, $newEmail, $emailTo, 'UsersManager_EmailChangeNotificationSubject');
+ }
+ }
+
+ private function sendUserInfoChangedEmail($type, $user, $newValue, $emailTo, $subject)
+ {
+ $deviceDescription = $this->getDeviceDescription();
+
+ $view = new View('@UsersManager/_userInfoChangedEmail.twig');
+ $view->type = $type;
+ $view->accountName = Common::sanitizeInputValue($user['login']);
+ $view->newEmail = Common::sanitizeInputValue($newValue);
+ $view->ipAddress = IP::getIpFromHeader();
+ $view->deviceDescription = $deviceDescription;
+
+ $mail = new Mail();
+
+ $mail->addTo($emailTo, $user['login']);
+ $mail->setSubject(Piwik::translate($subject));
+ $mail->setDefaultFromPiwik();
+ $mail->setWrappedHtmlBody($view);
+
+ $replytoEmailName = Config::getInstance()->General['login_password_recovery_replyto_email_name'];
+ $replytoEmailAddress = Config::getInstance()->General['login_password_recovery_replyto_email_address'];
+ $mail->setReplyTo($replytoEmailAddress, $replytoEmailName);
+
+ $mail->send();
+ }
+
+ private function sendPasswordChangedEmail($user)
+ {
+ $this->sendUserInfoChangedEmail('password', $user, null, $user['email'], 'UsersManager_PasswordChangeNotificationSubject');
+ }
+
+ private function getDeviceDescription()
+ {
+ $userAgent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '';
+
+ $uaParser = new DeviceDetector($userAgent);
+ $uaParser->parse();
+
+ $deviceName = ucfirst($uaParser->getDeviceName());
+ if (!empty($deviceName)) {
+ $description = $deviceName;
+ } else {
+ $description = Piwik::translate('General_Unknown');
+ }
+
+ $deviceBrand = $uaParser->getBrandName();
+ $deviceModel = $uaParser->getModel();
+ if (!empty($deviceBrand)
+ || !empty($deviceModel)
+ ) {
+ $parts = array_filter([$deviceBrand, $deviceModel]);
+ $description .= ' (' . implode(' ', $parts) . ')';
+ }
+
+ return $description;
+ }
}
diff --git a/plugins/UsersManager/lang/en.json b/plugins/UsersManager/lang/en.json
index a878d74971..5c54a7d238 100644
--- a/plugins/UsersManager/lang/en.json
+++ b/plugins/UsersManager/lang/en.json
@@ -156,6 +156,12 @@
"AreYouSureAddCapability": "Are you sure you want to give %1$s the %2$s capability for %3$s?",
"AreYouSureRemoveCapability": "Are you sure you want to remove the %1$s capability from %2$s for %3$s?",
"IncludedInUsersRole": "Included in this user's role.",
- "Capability": "Capability"
+ "Capability": "Capability",
+ "EmailChangeNotificationSubject": "Your Matomo account's email address has just been changed",
+ "EmailChangedEmail1": "The email address associated with your account has been changed to %1$s",
+ "EmailChangedEmail2": "This change was initiated from the following device: %1$s (IP address = %2$s).",
+ "IfThisWasYouIgnoreIfNot": "If this was you, feel free to ignore this email. If this was not you, please login, correct your email address, change your password and contact your Matomo administrator.",
+ "PasswordChangeNotificationSubject": "Your Matomo account's password has just been changed",
+ "PasswordChangedEmail": "Your password has just been changed. The change was initiated from the following device: %1$s (IP address = %2$s)."
}
}
diff --git a/plugins/UsersManager/templates/_userInfoChangedEmail.twig b/plugins/UsersManager/templates/_userInfoChangedEmail.twig
new file mode 100644
index 0000000000..73d0b15c77
--- /dev/null
+++ b/plugins/UsersManager/templates/_userInfoChangedEmail.twig
@@ -0,0 +1,14 @@
+<p>{{ 'General_HelloUser'|translate('<strong>' ~ accountName ~ '</strong>')|raw }}</p>
+
+{% if type == 'email' %}
+<p>{{ 'UsersManager_EmailChangedEmail1'|translate('<strong>' ~ newEmail ~ '</strong>')|raw }}.</p>
+
+<p>{{ 'UsersManager_EmailChangedEmail2'|translate(deviceDescription, ipAddress) }} {{ 'UsersManager_IfThisWasYouIgnoreIfNot'|translate }}</p>
+{% elseif type == 'password' %}
+<p>{{ 'UsersManager_PasswordChangedEmail'|translate(deviceDescription, ipAddress) }}</p>
+
+<p>{{ 'UsersManager_IfThisWasYouIgnoreIfNot'|translate }}</p>
+{% endif %}
+
+<p>{{ 'General_ThankYouForUsingMatomo'|translate }}!
+<br/>{{ 'General_TheMatomoTeam'|translate }}</p> \ No newline at end of file
diff --git a/plugins/UsersManager/tests/Integration/APITest.php b/plugins/UsersManager/tests/Integration/APITest.php
index 3942d1371d..e75f27a127 100644
--- a/plugins/UsersManager/tests/Integration/APITest.php
+++ b/plugins/UsersManager/tests/Integration/APITest.php
@@ -12,6 +12,7 @@ use Piwik\Access\Role\View;
use Piwik\Access\Role\Write;
use Piwik\Auth\Password;
use Piwik\Container\StaticContainer;
+use Piwik\Mail;
use Piwik\Option;
use Piwik\Piwik;
use Piwik\Plugins\SitesManager\API as SitesManagerAPI;
@@ -293,6 +294,11 @@ class APITest extends IntegrationTestCase
public function test_updateUser()
{
+ $capturedMails = [];
+ Piwik::addAction('Mail.send', function (Mail $mail) use (&$capturedMails) {
+ $capturedMails[] = $mail;
+ });
+
$identity = FakeAccess::$identity;
FakeAccess::$identity = $this->login; // ensure password will be checked against this user
$this->api->updateUser($this->login, 'newPassword', 'email@example.com', 'newAlias', false, $this->password);
@@ -307,6 +313,13 @@ class APITest extends IntegrationTestCase
$passwordHelper = new Password();
$this->assertTrue($passwordHelper->verify(UsersManager::getPasswordHash('newPassword'), $user['password']));
+
+ $subjects = array_map(function (Mail $mail) { return $mail->getSubject(); }, $capturedMails);
+ $this->assertEquals([
+ 'UsersManager_EmailChangeNotificationSubject', // sent twice to old email and new
+ 'UsersManager_EmailChangeNotificationSubject',
+ 'UsersManager_PasswordChangeNotificationSubject',
+ ], $subjects);
}
public function test_updateUser_doesNotChangePasswordIfFalsey()