mirror of
https://github.com/ntop/ntopng.git
synced 2026-05-03 09:20:10 +00:00
Addresses #3720 Alerts Refactor: alert_utils as module Alerts Refactor: notify_ntopng_start and notify_ntopng_stop Alerts Refactor: processAlertNotifications Alerts Refactor: checkStoreAlertsFromC Alerts Refactor: formatAlertNotification Alerts Refactor: notification_timestamp_rev Alerts Refactor: formatAlertMessage Alerts Refactor: getConfigsetAlertLink Alerts Refactor: alertNotificationActionToLabel Alerts Refactor: flushAlertsData Alerts Refactor: disableAlertsGeneration Alerts Refactor: newAlertsWorkingStatus and other Alerts Refactor: drawAlerts Alerts Refactor: drawAlertTables Alerts Refactor: printAlertTables Alerts Refactor: checkDeleteStoredAlerts Alerts Refactor: getUnpagedAlertOptions Alerts Refactor: getTabParameters Alerts Refactor: getAlerts Alerts Refactor: getNumAlerts Alerts Refactor: performAlertsQuery Alerts Refactor: sec2granularity Alerts Refactor: granularity2id Alerts Refactor: granularity2sec Alerts Refactor: alertEngineLabel Alerts Refactor: alertEngine Alerts Refactor: alertEngineRaw Alerts Refactor: alertTypeDescription Alerts Refactor: alertType Alerts Refactor: alertTypeLabel Alerts Refactor: alertTypeRaw Alerts Refactor: alertSeverity Alerts Refactor: alertSeverityLabel Alerts Refactor: alertSeverityRaw Alerts Refactor: get_make_room_keys Alerts Refactor: enterprise_alert_utils
241 lines
8.8 KiB
Lua
241 lines
8.8 KiB
Lua
--
|
|
-- (C) 2017-20 - ntop.org
|
|
--
|
|
|
|
local email = {}
|
|
|
|
local json = require("dkjson")
|
|
local alert_utils = require "alert_utils"
|
|
|
|
email.EXPORT_FREQUENCY = 60
|
|
email.prio = 200
|
|
|
|
local MAX_ALERTS_PER_EMAIL = 100
|
|
local MAX_NUM_SEND_ATTEMPTS = 5
|
|
local NUM_ATTEMPTS_KEY = "ntopng.alerts.modules_notifications_queue.email.num_attemps"
|
|
|
|
-- ##############################################
|
|
|
|
local function buildMessageHeader(now_ts, from, to, subject, body)
|
|
local now = os.date("%a, %d %b %Y %X", now_ts) -- E.g. "Tue, 3 Apr 2018 14:58:00"
|
|
local msg_id = "<" .. now_ts .. "." .. os.clock() .. "@ntopng>"
|
|
|
|
local lines = {
|
|
"From: " .. from,
|
|
"To: " .. to,
|
|
"Subject: " .. subject,
|
|
"Date: " .. now,
|
|
"Message-ID: " .. msg_id,
|
|
"Content-Type: text/html; charset=UTF-8",
|
|
}
|
|
|
|
return table.concat(lines, "\r\n") .. "\r\n\r\n" .. body .. "\r\n"
|
|
end
|
|
|
|
-- ##############################################
|
|
|
|
function email.isAvailable()
|
|
return(ntop.sendMail ~= nil)
|
|
end
|
|
|
|
-- ##############################################
|
|
|
|
function email.sendEmail(subject, message_body)
|
|
local smtp_server = ntop.getPref("ntopng.prefs.alerts.smtp_server")
|
|
local from_addr = ntop.getPref("ntopng.prefs.alerts.email_sender")
|
|
local to_addr = ntop.getPref("ntopng.prefs.alerts.email_recipient")
|
|
local username = ntop.getPref("ntopng.prefs.alerts.smtp_username")
|
|
local password = ntop.getPref("ntopng.prefs.alerts.smtp_password")
|
|
|
|
if isEmptyString(from_addr) or isEmptyString(to_addr) or isEmptyString(smtp_server) then
|
|
return false
|
|
end
|
|
|
|
local from = from_addr:gsub(".*<(.*)>", "%1")
|
|
local to = to_addr:gsub(".*<(.*)>", "%1")
|
|
local product = ntop.getInfo(false).product
|
|
local info = ntop.getHostInformation()
|
|
|
|
subject = product .. " [" .. info.instance_name .. "@" .. info.ip .. "] " .. subject
|
|
|
|
if not string.find(smtp_server, "://") then
|
|
smtp_server = "smtp://" .. smtp_server
|
|
end
|
|
|
|
local parts = string.split(to, "@")
|
|
|
|
if #parts == 2 then
|
|
local sender_domain = parts[2]
|
|
smtp_server = smtp_server .. "/" .. sender_domain
|
|
end
|
|
|
|
local message = buildMessageHeader(os.time(), from_addr, to_addr, subject, message_body)
|
|
return ntop.sendMail(from, to, message, smtp_server, username, password)
|
|
end
|
|
|
|
-- ##############################################
|
|
|
|
function email.dequeueAlerts(queue)
|
|
while true do
|
|
local notifications = ntop.lrangeCache(queue, 0, MAX_ALERTS_PER_EMAIL-1)
|
|
|
|
if not notifications then
|
|
break
|
|
end
|
|
|
|
local subject = ""
|
|
|
|
if #notifications > 1 then
|
|
subject = "(" .. i18n("alert_messages.x_alerts", {num=#notifications}) .. ")"
|
|
end
|
|
|
|
local message_body = {}
|
|
|
|
-- Multiple notifications
|
|
for _, json_message in ipairs(notifications) do
|
|
local notif = json.decode(json_message)
|
|
message_body[#message_body + 1] = alert_utils.formatAlertNotification(notif, {nohtml=true})
|
|
end
|
|
|
|
message_body = table.concat(message_body, "<br>")
|
|
|
|
local rv = email.sendEmail(subject, message_body)
|
|
|
|
if not rv then
|
|
local num_attemps = (tonumber(ntop.getCache(NUM_ATTEMPTS_KEY)) or 0) + 1
|
|
|
|
if num_attemps >= MAX_NUM_SEND_ATTEMPTS then
|
|
ntop.delCache(NUM_ATTEMPTS_KEY)
|
|
-- Prevent alerts starvation if the plugin is not working after max num attempts
|
|
ntop.delCache(queue)
|
|
return {success=false, error_message="Unable to send mails"}
|
|
else
|
|
ntop.setCache(NUM_ATTEMPTS_KEY, tostring(num_attemps))
|
|
return {success=true}
|
|
end
|
|
else
|
|
ntop.delCache(NUM_ATTEMPTS_KEY)
|
|
end
|
|
|
|
-- Remove the processed messages from the queue
|
|
ntop.ltrimCache(queue, MAX_ALERTS_PER_EMAIL, -1)
|
|
end
|
|
|
|
return {success=true}
|
|
end
|
|
|
|
-- ##############################################
|
|
|
|
function email.handlePost()
|
|
local message_info, message_severity
|
|
|
|
if(_POST["email_sender"] ~= nil) then
|
|
_POST["email_sender"] = unescapeHTML(_POST["email_sender"])
|
|
end
|
|
|
|
if(_POST["email_recipient"] ~= nil) then
|
|
_POST["email_recipient"] = unescapeHTML(_POST["email_recipient"])
|
|
end
|
|
|
|
if(_POST["send_test_email"] ~= nil) then
|
|
local success = email.sendEmail("TEST MAIL", "Email notification is working")
|
|
|
|
if success then
|
|
message_info = i18n("prefs.email_sent_successfully")
|
|
message_severity = "alert-success"
|
|
else
|
|
message_info = i18n("prefs.email_send_error", {url="https://www.ntop.org/guides/ntopng/web_gui/alerts.html#email"})
|
|
message_severity = "alert-danger"
|
|
end
|
|
end
|
|
|
|
return message_info, message_severity
|
|
end
|
|
|
|
-- ##############################################
|
|
|
|
function email.printPrefs(alert_endpoints, subpage_active, showElements)
|
|
print('<thead class="thead-light"><tr><th colspan="2" class="info">'..i18n("prefs.email_notification")..'</th></tr></thead>')
|
|
|
|
local elementToSwitch = {"row_email_notification_severity_preference", "email_sender", "email_recipient", "smtp_server", "smtp_username", "smtp_password", "alerts_test"}
|
|
|
|
prefsToggleButton(subpage_active, {
|
|
field = "toggle_email_notification",
|
|
pref = alert_endpoints.getAlertNotificationModuleEnableKey("email", true),
|
|
default = "0",
|
|
disabled = (showElements==false),
|
|
to_switch = elementToSwitch,
|
|
})
|
|
|
|
local showEmailNotificationPrefs = false
|
|
if ntop.getPref(alert_endpoints.getAlertNotificationModuleEnableKey("email")) == "1" then
|
|
showEmailNotificationPrefs = true
|
|
else
|
|
showEmailNotificationPrefs = false
|
|
end
|
|
|
|
multipleTableButtonPrefs(subpage_active.entries["notification_severity_preference"].title, subpage_active.entries["notification_severity_preference"].description,
|
|
alert_endpoints.getSeverityLabels(), alert_endpoints.getSeverityValues(), "error", "primary", "email_notification_severity_preference",
|
|
alert_endpoints.getAlertNotificationModuleSeverityKey("email"), nil, nil, nil, nil, showElements and showEmailNotificationPrefs)
|
|
|
|
prefsInputFieldPrefs(subpage_active.entries["email_notification_server"].title, subpage_active.entries["email_notification_server"].description,
|
|
"ntopng.prefs.alerts.", "smtp_server",
|
|
"", nil, showElements and showEmailNotificationPrefs, false, true, {attributes={spellcheck="false"}, required=true, pattern="^((smtp://)|(smtps://))?[a-zA-Z0-9-.]*(:[0-9]+)?$"})
|
|
|
|
prefsInputFieldPrefs(subpage_active.entries["email_notification_username"].title, subpage_active.entries["email_notification_username"].description,
|
|
"ntopng.prefs.alerts.", "smtp_username",
|
|
"", nil, showElements and showEmailNotificationPrefs, false, nil, {attributes={spellcheck="false"}, required=false})
|
|
|
|
prefsInputFieldPrefs(subpage_active.entries["email_notification_password"].title, subpage_active.entries["email_notification_password"].description,
|
|
"ntopng.prefs.alerts.", "smtp_password",
|
|
"", "password", showElements and showEmailNotificationPrefs, false, nil, {attributes={spellcheck="false"}, required=false})
|
|
|
|
prefsInputFieldPrefs(subpage_active.entries["email_notification_sender"].title, subpage_active.entries["email_notification_sender"].description,
|
|
"ntopng.prefs.alerts.", "email_sender",
|
|
"", nil, showElements and showEmailNotificationPrefs, false, nil, {attributes={spellcheck="false"}, pattern=email_peer_pattern, required=true})
|
|
|
|
prefsInputFieldPrefs(subpage_active.entries["email_notification_recipient"].title, subpage_active.entries["email_notification_recipient"].description,
|
|
"ntopng.prefs.alerts.", "email_recipient",
|
|
"", nil, showElements and showEmailNotificationPrefs, false, nil, {attributes={spellcheck="false"}, pattern=email_peer_pattern, required=true})
|
|
|
|
print('<tr id="alerts_test" style="' .. ternary(showEmailNotificationPrefs, "", "display:none;").. '"><td><button class="btn btn-secondary disable-on-dirty" type="button" onclick="sendTestEmail();" style="width:230px; float:left;">'..i18n("prefs.send_test_mail")..'</button></td></tr>')
|
|
|
|
print[[
|
|
<script>
|
|
function sendTestEmail() {
|
|
var params = {};
|
|
|
|
params.send_test_email = "";
|
|
params.csrf = "]] print(ntop.getRandomCSRFValue()) print[[";
|
|
|
|
var form = paramsToForm('<form method="post"></form>', params);
|
|
form.appendTo('body').submit();
|
|
}
|
|
|
|
function replace_email_special_characters(event) {
|
|
var form = $(this);
|
|
|
|
// e.g. when form is invalid
|
|
if(event.isDefaultPrevented())
|
|
return;
|
|
|
|
// this is necessary to escape "<" and ">" which are blocked on the backend to prevent injection
|
|
$("[name='email_sender'],[name='email_recipient']", form).each(function() {
|
|
var name = $(this).attr("name");
|
|
$(this).removeAttr("name");
|
|
|
|
$('<input type="hidden" name="' + name + '">')
|
|
.val(encodeURI($(this).val()))
|
|
.appendTo(form);
|
|
});
|
|
}
|
|
|
|
$(function() {
|
|
$("#external_alerts_form").submit(replace_email_special_characters);
|
|
});
|
|
</script>]]
|
|
end
|
|
|
|
-- ##############################################
|
|
|
|
return email
|