mirror of https://github.com/MISP/MISP
new: [mail] Move contact alert email to templates
parent
e2b1ba18a3
commit
17fb5db3cf
|
@ -405,16 +405,20 @@ class SendEmail
|
|||
/**
|
||||
* @param array $user
|
||||
* @param string $subject
|
||||
* @param CakeEmailBody $body
|
||||
* @param CakeEmailBody|null $bodyWithoutEncryption
|
||||
* @param SendEmailTemplate|string $body
|
||||
* @param string|false $bodyWithoutEncryption
|
||||
* @param array $replyToUser
|
||||
* @return bool True if e-mail is encrypted, false if not.
|
||||
* @throws Crypt_GPG_BadPassphraseException
|
||||
* @throws Crypt_GPG_Exception
|
||||
* @throws SendEmailException
|
||||
*/
|
||||
public function sendToUser(array $user, $subject, CakeEmailBody $body, CakeEmailBody $bodyWithoutEncryption = null, array $replyToUser = array())
|
||||
public function sendToUser(array $user, $subject, $body, $bodyWithoutEncryption = false, array $replyToUser = array())
|
||||
{
|
||||
if ($body instanceof SendEmailTemplate && $bodyWithoutEncryption !== false) {
|
||||
throw new InvalidArgumentException("When body is instance of SendEmailTemplate, \$bodyWithoutEncryption must be false.");
|
||||
}
|
||||
|
||||
if (Configure::read('MISP.disable_emailing')) {
|
||||
throw new SendEmailException('Emailing is currently disabled on this instance.');
|
||||
}
|
||||
|
@ -431,9 +435,18 @@ class SendEmail
|
|||
throw new SendEmailException('Encrypted messages are enforced and the message could not be encrypted for this user as no valid encryption key was found.');
|
||||
}
|
||||
|
||||
// If 'bodyonlyencrypted' is enabled and the user has no encryption key, use the alternate body (if it exists)
|
||||
if (Configure::read('GnuPG.bodyonlyencrypted') && !$canEncryptSmime && !$canEncryptGpg && $bodyWithoutEncryption) {
|
||||
$body = $bodyWithoutEncryption;
|
||||
// If 'GnuPG.bodyonlyencrypted' is enabled and the user has no encryption key, use the alternate body
|
||||
$hideDetails = Configure::read('GnuPG.bodyonlyencrypted') && !$canEncryptSmime && !$canEncryptGpg;
|
||||
|
||||
if ($body instanceof SendEmailTemplate) {
|
||||
$body->set('canEncryptSmime', $canEncryptSmime);
|
||||
$body->set('canEncryptGpg', $canEncryptGpg);
|
||||
$body = $body->render($hideDetails);
|
||||
} else {
|
||||
if ($hideDetails && $bodyWithoutEncryption) {
|
||||
$body = $bodyWithoutEncryption;
|
||||
}
|
||||
$body = new CakeEmailBody($body);
|
||||
}
|
||||
|
||||
$email = $this->create($user, $subject, $body, [], $replyToUser);
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
<?php
|
||||
class SendEmailTemplate
|
||||
{
|
||||
/** @var array */
|
||||
private $viewVars = [];
|
||||
|
||||
/** @var string */
|
||||
private $viewName;
|
||||
|
||||
public function __construct($viewName)
|
||||
{
|
||||
$this->viewName = $viewName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
*/
|
||||
public function set($key, $value)
|
||||
{
|
||||
$this->viewVars[$key] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $hideDetails True when GnuPG.bodyonlyencrypted is enabled and e-mail cannot be send in encrypted form
|
||||
* @return CakeEmailBody
|
||||
* @throws CakeException
|
||||
*/
|
||||
public function render($hideDetails = false)
|
||||
{
|
||||
$View = new View();
|
||||
$View->helpers = ['TextColour'];
|
||||
$View->loadHelpers();
|
||||
|
||||
$View->set($this->viewVars);
|
||||
$View->set('hideDetails', $hideDetails);
|
||||
|
||||
$View->viewPath = $View->layoutPath = 'Emails' . DS . 'html';
|
||||
try {
|
||||
$html = $View->render($this->viewName);
|
||||
} catch (MissingViewException $e) {
|
||||
$html = null; // HTMl template is optional
|
||||
}
|
||||
|
||||
$View->viewPath = $View->layoutPath = 'Emails' . DS . 'text';
|
||||
$View->hasRendered = false;
|
||||
$text = $View->render($this->viewName);
|
||||
|
||||
return new CakeEmailBody($text, $html);
|
||||
}
|
||||
}
|
|
@ -4,6 +4,7 @@ App::uses('CakeEmail', 'Network/Email');
|
|||
App::uses('RandomTool', 'Tools');
|
||||
App::uses('AttachmentTool', 'Tools');
|
||||
App::uses('TmpFileTool', 'Tools');
|
||||
App::uses('SendEmailTemplate', 'Tools');
|
||||
|
||||
/**
|
||||
* @property User $User
|
||||
|
@ -3202,10 +3203,6 @@ class Event extends AppModel
|
|||
}
|
||||
$subject = "[" . Configure::read('MISP.org') . " MISP] Event $id - $subject$threatLevel" . strtoupper($subjMarkingString);
|
||||
|
||||
$eventUrl = $this->__getAnnounceBaseurl() . "/events/view/" . $id;
|
||||
$bodyNoEnc = __("A new or modified event was just published on %s", $eventUrl) . "\n\n";
|
||||
$bodyNoEnc .= __("If you would like to unsubscribe from receiving such alert e-mails, simply\ndisable publish alerts via %s", $this->__getAnnounceBaseurl() . '/users/edit');
|
||||
|
||||
$userCount = count($usersWithAccess);
|
||||
$this->UserSetting = ClassRegistry::init('UserSetting');
|
||||
foreach ($usersWithAccess as $k => $user) {
|
||||
|
@ -3219,8 +3216,8 @@ class Event extends AppModel
|
|||
])[0];
|
||||
|
||||
if ($this->UserSetting->checkPublishFilter($user, $eventForUser)) {
|
||||
$body = $this->renderAlertEmail($eventForUser, $user, $oldpublish);
|
||||
$this->User->sendEmail(['User' => $user], $body, $bodyNoEnc, $subject);
|
||||
$body = $this->prepareAlertEmail($eventForUser, $user, $oldpublish);
|
||||
$this->User->sendEmail(['User' => $user], $body, false, $subject);
|
||||
}
|
||||
if ($jobId) {
|
||||
$this->Job->saveProgress($jobId, null, $k / $userCount * 100);
|
||||
|
@ -3235,39 +3232,22 @@ class Event extends AppModel
|
|||
|
||||
/**
|
||||
* @param array $event
|
||||
* @param array $user
|
||||
* @param array $user E-mail receiver
|
||||
* @param int|null $oldpublish Timestamp of previous publishing.
|
||||
* @param bool $contactAlert
|
||||
* @return CakeEmailBody
|
||||
* @return SendEmailTemplate
|
||||
* @throws CakeException
|
||||
*/
|
||||
private function renderAlertEmail(array $event, array $user, $oldpublish = null, $contactAlert = false)
|
||||
private function prepareAlertEmail(array $event, array $user, $oldpublish = null)
|
||||
{
|
||||
$View = new View();
|
||||
$View->helpers = ['TextColour'];
|
||||
$View->loadHelpers();
|
||||
|
||||
$View->set('event', $event);
|
||||
$View->set('user', $user);
|
||||
$View->set('oldPublishTimestamp', $oldpublish);
|
||||
$View->set('baseurl', $this->__getAnnounceBaseurl());
|
||||
$View->set('distributionLevels', $this->distributionLevels);
|
||||
$View->set('analysisLevels', $this->analysisLevels);
|
||||
$View->set('contactAlert', $contactAlert);
|
||||
|
||||
try {
|
||||
$View->viewPath = $View->layoutPath = 'Emails' . DS . 'html';
|
||||
$html = $View->render('alert');
|
||||
} catch (MissingViewException $e) {
|
||||
$html = null; // HTMl template is optional
|
||||
}
|
||||
|
||||
$View->hasRendered = false;
|
||||
$View->viewPath = $View->layoutPath = 'Emails' . DS . 'text';
|
||||
$text = $View->render('alert');
|
||||
|
||||
require_once APP . '/Lib/Tools/SendEmail.php'; // TODO
|
||||
return new CakeEmailBody($text, $html);
|
||||
$template = new SendEmailTemplate('alert');
|
||||
$template->set('event', $event);
|
||||
$template->set('user', $user);
|
||||
$template->set('oldPublishTimestamp', $oldpublish);
|
||||
$template->set('baseurl', $this->__getAnnounceBaseurl());
|
||||
$template->set('distributionLevels', $this->distributionLevels);
|
||||
$template->set('analysisLevels', $this->analysisLevels);
|
||||
$template->set('tlp', $this->getEmailSubjectMarkForEvent($event));
|
||||
return $template;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -3327,42 +3307,33 @@ class Event extends AppModel
|
|||
$tplColorString = $this->getEmailSubjectMarkForEvent($event);
|
||||
$subject = "[" . Configure::read('MISP.org') . " MISP] Need info about event $id - " . strtoupper($tplColorString);
|
||||
$result = true;
|
||||
foreach ($orgMembers as $reporter) {
|
||||
list($bodyevent, $body) = $this->__buildContactEventEmailBody($user, $reporter, $message, $event);
|
||||
$result = $this->User->sendEmail($reporter, $bodyevent, $body, $subject, $user) && $result;
|
||||
foreach ($orgMembers as $eventReporter) {
|
||||
$body = $this->prepareContactAlertEmail($user, $eventReporter, $message, $event);
|
||||
$result = $this->User->sendEmail($eventReporter, $body, false, $subject, $user) && $result;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
private function __buildContactEventEmailBody(array $user, array $reporter, $message, array $event)
|
||||
/**
|
||||
* @param array $user
|
||||
* @param array $eventReporter
|
||||
* @param string $message
|
||||
* @param array $event
|
||||
* @return SendEmailTemplate
|
||||
*/
|
||||
private function prepareContactAlertEmail(array $user, array $eventReporter, $message, array $event)
|
||||
{
|
||||
// The mail body, h() is NOT needed as we are sending plain-text mails.
|
||||
$body = "";
|
||||
$body .= "Hello, \n";
|
||||
$body .= "\n";
|
||||
$body .= "Someone wants to get in touch with you concerning a MISP event. \n";
|
||||
$body .= "\n";
|
||||
$body .= "You can reach them at " . $user['User']['email'] . "\n";
|
||||
if (!empty($user['User']['gpgkey'])) {
|
||||
$body .= "Their GnuPG key is added as attachment to this email. \n";
|
||||
}
|
||||
if (!empty($user['User']['certif_public'])) {
|
||||
$body .= "Their Public certificate is added as attachment to this email. \n";
|
||||
}
|
||||
$body .= "\n";
|
||||
$body .= "They wrote the following message: \n";
|
||||
$body .= $message . "\n";
|
||||
$body .= "\n";
|
||||
$body .= "\n";
|
||||
$body .= "The event is the following: \n";
|
||||
|
||||
$full = $body;
|
||||
$body .= $this->__getAnnounceBaseurl() . '/events/view/' . $event['Event']['id'] . "\n";
|
||||
|
||||
$rendered = $this->renderAlertEmail($event, $reporter);
|
||||
$full .= $rendered->text;
|
||||
|
||||
return array($body, $full);
|
||||
$template = new SendEmailTemplate('alert_contact');
|
||||
$template->set('event', $event);
|
||||
$template->set('requestor', $user);
|
||||
$template->set('message', $message);
|
||||
$template->set('user', $this->User->rearrangeToAuthForm($eventReporter));
|
||||
$template->set('baseurl', $this->__getAnnounceBaseurl());
|
||||
$template->set('distributionLevels', $this->distributionLevels);
|
||||
$template->set('analysisLevels', $this->analysisLevels);
|
||||
$template->set('contactAlert', true);
|
||||
$template->set('tlp', $this->getEmailSubjectMarkForEvent($event));
|
||||
return $template;
|
||||
}
|
||||
|
||||
public function captureSGForElement($element, $user, $server=false)
|
||||
|
|
|
@ -807,13 +807,7 @@ class User extends AppModel
|
|||
$sendEmail = new SendEmail($gpg);
|
||||
|
||||
try {
|
||||
$encrypted = $sendEmail->sendToUser(
|
||||
$user,
|
||||
$subject,
|
||||
is_string($body) ? new CakeEmailBody($body) : $body,
|
||||
$bodyNoEnc ? (is_string($bodyNoEnc) ? new CakeEmailBody($bodyNoEnc) : $bodyNoEnc): null,
|
||||
$replyToUser ?: []
|
||||
);
|
||||
$encrypted = $sendEmail->sendToUser($user, $subject, $body, $bodyNoEnc,$replyToUser ?: []);
|
||||
|
||||
} catch (SendEmailException $e) {
|
||||
$this->logException("Exception during sending e-mail", $e);
|
||||
|
|
|
@ -1,4 +1,19 @@
|
|||
<?php
|
||||
if (!isset($oldPublishTimestamp)) {
|
||||
$oldPublishTimestamp = null;
|
||||
}
|
||||
|
||||
if (!isset($contactAlert)) {
|
||||
$contactAlert = false;
|
||||
}
|
||||
|
||||
if ($hideDetails) { // Used when GnuPG.bodyonlyencrypted is enabled and e-mail cannot be send in encrypted form
|
||||
$eventUrl = $baseurl . "/events/view/" . $event['Event']['id'];
|
||||
echo __("A new or modified event was just published on %s", $eventUrl) . PHP_EOL . PHP_EOL;
|
||||
echo __("If you would like to unsubscribe from receiving such alert e-mails, simply\ndisable publish alerts via %s", $baseurl . '/users/edit');
|
||||
return;
|
||||
}
|
||||
|
||||
$renderAttributes = function(array $attributes, $indent = ' ') use ($oldPublishTimestamp) {
|
||||
$appendlen = 20;
|
||||
foreach ($attributes as $attribute) {
|
||||
|
@ -83,12 +98,12 @@ foreach ($event['RelatedEvent'] as $relatedEvent) {
|
|||
<?php endif; ?>
|
||||
|
||||
<?php if (!empty($event['Attribute'])): ?>
|
||||
Attributes<?= isset($oldPublishTimestamp) ? ' (* indicates a new or modified attribute since last update):' : ':' ?>
|
||||
Attributes<?= isset($oldPublishTimestamp) ? " (* indicates a new or modified attribute since last update):\n" : ":\n" ?>
|
||||
<?= $renderAttributes($event['Attribute']) ?>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (!empty($event['Object'])): ?>
|
||||
Objects<?= isset($oldPublishTimestamp) ? ' (* indicates a new or modified object since last update):' : ':' ?>
|
||||
Objects<?= isset($oldPublishTimestamp) ? " (* indicates a new or modified object since last update):\n" : ":\n" ?>
|
||||
<?= $renderObjects($event['Object']) ?>
|
||||
<?php endif; ?>
|
||||
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
Hello,
|
||||
|
||||
Someone wants to get in touch with you concerning a MISP event.
|
||||
|
||||
You can reach them at <?= $requestor['User']['email'] ?>
|
||||
<?php if (!empty($requestor['User']['gpgkey'])): ?>
|
||||
Their PGP key is added as attachment to this email.
|
||||
<?php endif; ?>
|
||||
<?php if (!empty($requestor['User']['certif_public'])): ?>
|
||||
Their Public certificate is added as attachment to this email.
|
||||
<?php endif; ?>
|
||||
|
||||
They wrote the following message:
|
||||
<?= $message ?>
|
||||
|
||||
|
||||
The event is the following:
|
||||
<?php
|
||||
if ($hideDetails) {
|
||||
echo $baseurl . ' /events/view/' . $event['Event']['id'];
|
||||
} else {
|
||||
require __DIR__ . '/alert.ctp'; // include event details
|
||||
}
|
Loading…
Reference in New Issue