aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/lua
diff options
context:
space:
mode:
authorrm-minus-rf <rm.minus.rf@protonmail.com>2020-04-14 11:42:28 +0200
committerrm-minus-rf <rm.minus.rf@protonmail.com>2020-04-14 11:42:28 +0200
commit0d13c724df534012de7e41c5d5b743a7d9314431 (patch)
tree301f5c459a206a09b1449bc98012c3b1e062fb38 /src/plugins/lua
parent29f38bde308faed44b6298338451fb7b82923c65 (diff)
downloadrspamd-0d13c724df534012de7e41c5d5b743a7d9314431.tar.gz
rspamd-0d13c724df534012de7e41c5d5b743a7d9314431.zip
[Feature] allow variables in force_actions messages
See https://github.com/rspamd/rspamd/issues/3335 for details.
Diffstat (limited to 'src/plugins/lua')
-rw-r--r--src/plugins/lua/force_actions.lua63
1 files changed, 63 insertions, 0 deletions
diff --git a/src/plugins/lua/force_actions.lua b/src/plugins/lua/force_actions.lua
index 108c0b76e..8e645290e 100644
--- a/src/plugins/lua/force_actions.lua
+++ b/src/plugins/lua/force_actions.lua
@@ -29,6 +29,7 @@ local lua_util = require "lua_util"
local rspamd_cryptobox_hash = require "rspamd_cryptobox_hash"
local rspamd_expression = require "rspamd_expression"
local rspamd_logger = require "rspamd_logger"
+local lua_selectors = require "lua_selectors"
local function gen_cb(expr, act, pool, message, subject, raction, honor, limit, least)
@@ -63,6 +64,66 @@ local function gen_cb(expr, act, pool, message, subject, raction, honor, limit,
return function(task)
+ local function fill_vars(repl, var_class, var_payload)
+ -- fill template vars prefixed with
+ -- 'selector::' => fill with value extracted by a selector
+ -- 'symbol::' => fill with matching symbol option string(s)
+ -- 'task::' => fill with matching task attribute
+ -- (only queue_id and uid allowed)
+
+ if var_class == "selector" then
+ local selector = lua_selectors.create_selector_closure(rspamd_config, var_payload, '', true)
+ if not selector then
+ rspamd_logger.errx(rspamd_config, 'could not create selector [%1]', var_payload)
+ return "((could not create selector))"
+ end
+ local extracted = selector(task)
+ if extracted then
+ -- replace non ascii chars
+ if type(extracted) == 'table' then
+ extracted = table.concat(extracted, ',')
+ end
+ extracted = string.gsub(extracted, '[\128-\255]', '?')
+ else
+ rspamd_logger.errx(rspamd_config, 'could not extract value with selector [%1]', var_payload)
+ extracted = '((error extracting value))'
+ end
+ return extracted
+ end
+
+ if var_class == "symbol" then
+ local symb_opts
+ local symb_strs = {}
+ if task:has_symbol(var_payload) then
+ local symb_tbl = task:get_symbol(var_payload)
+ for _,symb in ipairs(symb_tbl) do
+ local symb_opts = symb.options
+ if symb_opts then
+ -- replace non ascii chars
+ symb_strs[#symb_strs+1] = string.gsub(table.concat(symb_opts, ','), '[\128-\255]', '?')
+ end
+ end
+ symb_str = table.concat(symb_strs, ',')
+ else
+ symb_str = '((symbol not found))'
+ end
+ return symb_str
+ end
+
+ -- NOTE-TO-VSTAKHOV: would it make sense to export task:get_queue_id and task:get_uid as selector data definition?
+ if var_class == "task" then
+ local attr_val = '((unknown task attribute))'
+ if var_payload == 'queue_id' then
+ attr_val = task:get_queue_id()
+ elseif var_payload == 'uid' then
+ attr_val = task:get_uid()
+ end
+ return attr_val
+ end
+
+ end
+
+
local cact = task:get_metric_action('default')
if cact == act then
return false
@@ -83,6 +144,8 @@ local function gen_cb(expr, act, pool, message, subject, raction, honor, limit,
if least then flags = "least" end
if type(message) == 'string' then
+ -- fill vars in return message
+ message = string.gsub(message, '(${(.-)::(.-)})', fill_vars)
task:set_pre_result(act, message, N, nil, nil, flags)
else