]> source.dussan.org Git - rspamd.git/commitdiff
[Minor] Force actions: support expressions & alternate message syntax 1381/head
authorAndrew Lewis <nerf@judo.za.org>
Fri, 27 Jan 2017 16:03:52 +0000 (18:03 +0200)
committerAndrew Lewis <nerf@judo.za.org>
Fri, 27 Jan 2017 16:03:52 +0000 (18:03 +0200)
src/plugins/lua/force_actions.lua

index 66c23d773fc9db3229647b2a23b07f353b5aa0ac..caee6f264890fd631f178dd53327d3fcb53e70b3 100644 (file)
@@ -20,13 +20,50 @@ limitations under the License.
 local E = {}
 local N = 'force_actions'
 
-local function gen_cb(sym, act, message)
-  return function(task)
-    local s = task:get_symbol(sym)
-    if not s then return end
-    task:set_pre_result(act, message)
-    return true
+local fun = require "fun"
+local rspamd_cryptobox_hash = require "rspamd_cryptobox_hash"
+local rspamd_expression = require "rspamd_expression"
+local rspamd_logger = require "rspamd_logger"
+
+local function gen_cb(expr, act, pool, message)
+
+  local function parse_atom(str)
+    local atom = table.concat(fun.totable(fun.take_while(function(c)
+      if string.find(', \t()><+!|&\n', c) then
+        return false
+      end
+      return true
+    end, fun.iter(str))), '')
+    return atom
+  end
+
+  local function process_atom(atom, task)
+    local f_ret = task:has_symbol(atom)
+    if f_ret then
+      return 1
+    end
+    return 0
+  end
+
+  local e, err = rspamd_expression.create(expr, {parse_atom, process_atom}, pool)
+  if err then
+    rspamd_logger.errx(rspamd_config, 'Couldnt create expression [%1]: %2', expr, err)
+    return
   end
+
+  return function(task)
+
+    if e:process(task) == 1 then
+      if message then
+        task:set_pre_result(act, message)
+      else
+        task:set_pre_result(act)
+      end
+      return true
+    end
+
+  end, e:atoms()
+
 end
 
 local function configure_module()
@@ -37,16 +74,33 @@ local function configure_module()
   if type(opts.actions) ~= 'table' then
     return false
   end
-  for action, symbols in pairs(opts.actions) do
-    if type(symbols) == 'table' then
-      for _, symbol in ipairs(symbols) do
-        local message = (opts.messages or E)[symbol]
-        local id = rspamd_config:register_symbol({
-          type = 'normal',
-          name = 'FORCE_ACTION_ON_' .. symbol,
-          callback = gen_cb(symbol, action, message),
-        })
-        rspamd_config:register_dependency(id, symbol)
+  for action, expressions in pairs(opts.actions) do
+    if type(expressions) == 'table' then
+      for _, expr in ipairs(expressions) do
+        local message
+        if type(expr) == 'table' then
+          message = expr[2]
+          expr = expr[1]
+        else
+          message = (opts.messages or E)[expr]
+        end
+        if type(expr) == 'string' then
+          local cb, atoms = gen_cb(expr, action, rspamd_config:get_mempool(), message)
+          if cb and atoms then
+            local h = rspamd_cryptobox_hash.create()
+            h:update(expr)
+            local name = 'FORCE_ACTION_' .. string.upper(string.sub(h:hex(), 1, 12))
+            local id = rspamd_config:register_symbol({
+              type = 'normal',
+              name = name,
+              callback = cb,
+            })
+            for _, a in ipairs(atoms) do
+              rspamd_config:register_dependency(id, a)
+            end
+            rspamd_logger.infox(rspamd_config, 'Registered symbol %1 <%2> with dependencies [%3]', name, expr, table.concat(atoms, ','))
+          end
+        end
       end
     end
   end