local rspamd_mempool = require "rspamd_mempool"
local redis_params
-local external_map -- used when settings are queried from an external resource
local settings = {}
local N = "settings"
-- Check limit for a task
local function check_settings(task)
local function check_specific_setting(rule, matched)
- local res = false
-
local function process_atom(atom)
local elt = rule.checks[atom]
return 0
end
- res = rule.expression and rule.expression:process(process_atom)
+ local res = rule.expression and rule.expression:process(process_atom) or rule.implicit
if res and res > 0 then
if rule['whitelist'] then
return
end
- if external_map then
- local selector_result = external_map.selector(task)
-
- if selector_result then
- external_map.map:get_key(selector_result, nil, task)
- -- No more selection logic
- return
- else
- rspamd_logger.infox("cannot query selector to make external map request")
- end
- end
-- Match rules according their order
local applied = false
for _,s in ipairs(settings[pri]) do
local matched = {}
- lua_util.debugm(N, task, "check for settings element %s",
- s.name)
local result = check_specific_setting(s.rule, matched)
+ lua_util.debugm(N, task, "check for settings element %s; result = %s",
+ s.name, result)
-- Can use xor here but more complicated for reading
if result then
- if s.rule['apply'] then
+ if s.rule.apply then
if s.rule.id then
-- Extract static settings
local cached = lua_settings.settings_by_id(s.rule.id)
end
applied = true
+ elseif s.rule.external_map then
+ local external_map = s.rule.external_map
+ local selector_result = external_map.selector(task)
+
+ if selector_result then
+ external_map.map:get_key(selector_result, nil, task)
+ -- No more selection logic
+ return
+ else
+ rspamd_logger.infox("cannot query selector to make external map request")
+ end
end
if s.rule['symbols'] then
-- Add symbols, specified in the settings
return out
end
+local function gen_settings_external_cb(name)
+ return function (result, err_or_data, code, task)
+ if result then
+ local parser = ucl.parser()
+
+ local res,ucl_err = parser:parse_string(err_or_data)
+ if not res then
+ rspamd_logger.warnx(task, 'cannot parse settings from the external map %s: %s',
+ name, ucl_err)
+ else
+ local obj = parser:get_object()
+ rspamd_logger.infox(task, "<%s> apply settings according to the external map %s",
+ name, task:get_message_id())
+ apply_settings(task, obj, nil, 'external_map')
+ end
+ else
+ rspamd_logger.infox(task, "<%s> no settings returned from the external map %s: %s (code = %s)",
+ task:get_message_id(), name, err_or_data, code)
+ end
+ end
+end
+
-- Process IP address: converted to a table {ip, mask}
local function process_ip_condition(ip)
local out = {}
name, nchecks)
end
else
- lua_util.debugm(N, rspamd_config, 'registered settings %s with no checks',
- name)
+ if not elt.disabled then
+ lua_util.debugm(N, rspamd_config, 'registered settings %s with no checks, assume it as implicit',
+ name)
+ out.implicit = 1
+ end
end
-- Process symbols part/apply part
out['symbols'] = elt['symbols']
end
+ --[[
+ external_map = {
+ map = { ... };
+ selector = "...";
+ }
+ --]]
+ if type(elt.external_map) == 'table'
+ and elt.external_map.map and elt.external_map.selector then
+ local maybe_external_map = {}
+ maybe_external_map.map = lua_maps.map_add_from_ucl(elt.external_map.map, "",
+ string.format("External map for settings element %s", name),
+ gen_settings_external_cb(name))
+ maybe_external_map.selector = lua_selectors.create_selector_closure_fn(rspamd_config,
+ rspamd_config, elt.external_map.selector, ";", lua_selectors.kv_table_from_pairs)
+
+ if maybe_external_map.map and maybe_external_map.selector then
+ rspamd_logger.infox(rspamd_config, "added external map for user's settings %s", name)
+ out.external_map = maybe_external_map
+ else
+ local incorrect_element
+ if not maybe_external_map.map then
+ incorrect_element = "map definition"
+ else
+ incorrect_element = "selector definition"
+ end
+ rspamd_logger.warnx(rspamd_config, "cannot add external map for user's settings; incorrect element: %s",
+ incorrect_element)
+ out.external_map = nil
+ end
+ end
- if elt['apply'] then
- -- Just insert all metric results to the action key
- out['apply'] = elt['apply']
- elseif elt['whitelist'] or elt['want_spam'] then
- out['whitelist'] = true
- else
- rspamd_logger.errx(rspamd_config, "no actions in settings: " .. name)
- return nil
+ if not elt.external_map then
+ if elt['apply'] then
+ -- Just insert all metric results to the action key
+ out['apply'] = elt['apply']
+ elseif elt['whitelist'] or elt['want_spam'] then
+ out['whitelist'] = true
+ else
+ rspamd_logger.errx(rspamd_config, "no actions in settings: " .. name)
+ return nil
+ end
end
if allow_ids then
settings_initialized = true
lua_settings.load_all_settings(true)
- rspamd_logger.infox(rspamd_config, 'loaded %1 elements of settings', nrules)
+ rspamd_logger.infox(rspamd_config, 'loaded %s elements of settings', nrules)
return true
end
end
end
-local function settings_external_cb(result, err_or_data, code, task)
- if result then
- local parser = ucl.parser()
-
- local res,ucl_err = parser:parse_string(err_or_data)
- if not res then
- rspamd_logger.warnx(task, 'cannot parse settings from the external map: %s',
- ucl_err)
- else
- local obj = parser:get_object()
- rspamd_logger.infox(task, "<%s> apply settings according to the external map",
- task:get_message_id())
- apply_settings(task, obj, nil, 'external_map')
- end
- else
- rspamd_logger.infox(task, "<%s> no settings returned from the external map: %s (code = %s)",
- task:get_message_id(), err_or_data, code)
- end
-end
-
local redis_section = rspamd_config:get_all_opt("settings_redis")
local redis_key_handlers = {}
end, set_section)
)
- --[[
- external_map = {
- map = { ... };
- selector = "...";
- }
- --]]
- if type(set_section.external_map) == 'table'
- and set_section.external_map.map and set_section.external_map.selector then
- local maybe_external_map = {}
- maybe_external_map.map = lua_maps.map_add_from_ucl(set_section.external_map.map, "", "External map for settings",
- settings_external_cb)
- maybe_external_map.selector = lua_selectors.create_selector_closure_fn(rspamd_config,
- rspamd_config, set_section.external_map.selector, ";", lua_selectors.kv_table_from_pairs)
-
- if maybe_external_map.map and maybe_external_map.selector then
- rspamd_logger.infox(rspamd_config, "added external map for user's settings")
- external_map = maybe_external_map
- set_section.external_map = nil -- to avoid internal processing
- else
- rspamd_logger.warnx(rspamd_config, "cannot add external map for user's settings")
- end
- end
rspamd_config:add_post_init(function ()
process_settings_table(set_section, true, settings_map_pool, true)
end, 100)