diff options
author | Vsevolod Stakhov <vsevolod@rspamd.com> | 2023-08-07 11:41:28 +0100 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@rspamd.com> | 2023-08-07 11:41:28 +0100 |
commit | 662145d0554de5e769b92dab2d41173a98adcee5 (patch) | |
tree | ec28311a0bce6181f248ba7b50304293ad764e44 /lualib/plugins | |
parent | bbd88232db43d18f5e0de5a6502848d4074621c5 (diff) | |
download | rspamd-662145d0554de5e769b92dab2d41173a98adcee5.tar.gz rspamd-662145d0554de5e769b92dab2d41173a98adcee5.zip |
[Minor] Reformat all Lua code, no functional changes
Diffstat (limited to 'lualib/plugins')
-rw-r--r-- | lualib/plugins/dmarc.lua | 47 | ||||
-rw-r--r-- | lualib/plugins/neural.lua | 264 | ||||
-rw-r--r-- | lualib/plugins/rbl.lua | 62 |
3 files changed, 192 insertions, 181 deletions
diff --git a/lualib/plugins/dmarc.lua b/lualib/plugins/dmarc.lua index 24efb5078..6acf982c3 100644 --- a/lualib/plugins/dmarc.lua +++ b/lualib/plugins/dmarc.lua @@ -73,7 +73,7 @@ exports.default_settings = { -- Returns a key used to be inserted into dmarc report sample -exports.dmarc_report = function (task, settings, data) +exports.dmarc_report = function(task, settings, data) local rspamd_lua_utils = require "lua_util" local E = {} @@ -100,16 +100,15 @@ exports.dmarc_report = function (task, settings, data) local res = table.concat({ ip, data.spf_ok, data.dkim_ok, disposition_to_return, (data.sampled_out and 'sampled_out' or ''), data.domain, - dkim_pass, dkim_fail, dkim_temperror, dkim_permerror, data.spf_domain, data.spf_result}, ',') + dkim_pass, dkim_fail, dkim_temperror, dkim_permerror, data.spf_domain, data.spf_result }, ',') return res end - exports.gen_munging_callback = function(munging_opts, settings) local rspamd_util = require "rspamd_util" local lua_mime = require "lua_mime" - return function (task) + return function(task) if munging_opts.mitigate_allow_only then if not task:has_symbol(settings.symbols.allow) then lua_util.debugm(N, task, 'skip munging, no %s symbol', @@ -131,11 +130,11 @@ exports.gen_munging_callback = function(munging_opts, settings) end end if munging_opts.mitigate_strict_only then - local s = task:get_symbol(settings.symbols.allow) or {[1] = {}} + local s = task:get_symbol(settings.symbols.allow) or { [1] = {} } local sopts = s[1].options or {} local seen_strict - for _,o in ipairs(sopts) do + for _, o in ipairs(sopts) do if o == 'reject' or o == 'quarantine' then seen_strict = true break @@ -150,7 +149,7 @@ exports.gen_munging_callback = function(munging_opts, settings) end end if munging_opts.munge_map_condition then - local accepted,trace = munging_opts.munge_map_condition:process(task) + local accepted, trace = munging_opts.munge_map_condition:process(task) if not accepted then lua_util.debugm(task, 'skip munging, maps condition not satisfied: (%s)', trace) @@ -159,10 +158,10 @@ exports.gen_munging_callback = function(munging_opts, settings) end end -- Now, look for domain for munging - local mr = task:get_recipients({ 'mime', 'orig'}) + local mr = task:get_recipients({ 'mime', 'orig' }) local rcpt_found if mr then - for _,r in ipairs(mr) do + for _, r in ipairs(mr) do if r.domain and munging_opts.list_map:get_key(r.addr) then rcpt_found = r break @@ -176,7 +175,7 @@ exports.gen_munging_callback = function(munging_opts, settings) return end - local from = task:get_from({ 'mime', 'orig'}) + local from = task:get_from({ 'mime', 'orig' }) if not from or not from[1] then lua_util.debugm(task, 'skip munging, from is bad') @@ -204,7 +203,7 @@ exports.gen_munging_callback = function(munging_opts, settings) local add_hdrs = { ['From'] = { order = 1, value = hdr_encoded }, } - local remove_hdrs = {['From'] = 0} + local remove_hdrs = { ['From'] = 0 } local nreply = from.addr if munging_opts.reply_goes_to_list then @@ -222,9 +221,9 @@ exports.gen_munging_callback = function(munging_opts, settings) remove_hdrs['Reply-To'] = 1 end - add_hdrs['Reply-To'] = {order = 0, value = nreply} + add_hdrs['Reply-To'] = { order = 0, value = nreply } - add_hdrs['X-Original-From'] = { order = 0, value = orig_from_encoded} + add_hdrs['X-Original-From'] = { order = 0, value = orig_from_encoded } lua_mime.modify_headers(task, { remove = remove_hdrs, add = add_hdrs @@ -239,12 +238,12 @@ end local function gen_dmarc_grammar() local lpeg = require "lpeg" lpeg.locale(lpeg) - local space = lpeg.space^0 - local name = lpeg.C(lpeg.alpha^1) * space - local sep = space * (lpeg.S("\\;") * space) + (lpeg.space^1) - local value = lpeg.C(lpeg.P(lpeg.graph - sep)^1) - local pair = lpeg.Cg(name * "=" * space * value) * sep^-1 - local list = lpeg.Cf(lpeg.Ct("") * pair^0, rawset) + local space = lpeg.space ^ 0 + local name = lpeg.C(lpeg.alpha ^ 1) * space + local sep = space * (lpeg.S("\\;") * space) + (lpeg.space ^ 1) + local value = lpeg.C(lpeg.P(lpeg.graph - sep) ^ 1) + local pair = lpeg.Cg(name * "=" * space * value) * sep ^ -1 + local list = lpeg.Cf(lpeg.Ct("") * pair ^ 0, rawset) local version = lpeg.P("v") * space * lpeg.P("=") * space * lpeg.P("DMARC1") local record = version * sep * list @@ -297,7 +296,7 @@ local function dmarc_check_record(log_obj, record, is_tld) result.strict_dkim = true elseif dkim_pol ~= 'r' then failed_policy = 'adkim tag has invalid value: ' .. dkim_pol - return false,failed_policy + return false, failed_policy end end @@ -307,7 +306,7 @@ local function dmarc_check_record(log_obj, record, is_tld) result.strict_spf = true elseif spf_pol ~= 'r' then failed_policy = 'aspf tag has invalid value: ' .. spf_pol - return false,failed_policy + return false, failed_policy end end @@ -319,7 +318,7 @@ local function dmarc_check_record(log_obj, record, is_tld) result.dmarc_policy = 'quarantine' elseif (policy ~= 'none') then failed_policy = 'p tag has invalid value: ' .. policy - return false,failed_policy + return false, failed_policy end end @@ -336,7 +335,7 @@ local function dmarc_check_record(log_obj, record, is_tld) result.dmarc_policy = 'none' elseif (subdomain_policy ~= 'none') then failed_policy = 'sp tag has invalid value: ' .. subdomain_policy - return false,failed_policy + return false, failed_policy end end result.pct = elts['pct'] @@ -349,7 +348,7 @@ local function dmarc_check_record(log_obj, record, is_tld) end result.raw_elts = elts else - return false,false -- Ignore garbage + return false, false -- Ignore garbage end return true, result diff --git a/lualib/plugins/neural.lua b/lualib/plugins/neural.lua index 05dace489..6e88ef21c 100644 --- a/lualib/plugins/neural.lua +++ b/lualib/plugins/neural.lua @@ -96,7 +96,6 @@ local module_config = rspamd_config:get_all_opt(N) settings = lua_util.override_defaults(settings, module_config) local redis_params = lua_redis.parse_redis_server('neural') - local redis_lua_script_vectors_len = "neural_train_size.lua" local redis_lua_script_maybe_invalidate = "neural_maybe_invalidate.lua" local redis_lua_script_maybe_lock = "neural_maybe_lock.lua" @@ -106,17 +105,17 @@ local redis_script_id = {} local function load_scripts() redis_script_id.vectors_len = lua_redis.load_redis_script_from_file(redis_lua_script_vectors_len, - redis_params) + redis_params) redis_script_id.maybe_invalidate = lua_redis.load_redis_script_from_file(redis_lua_script_maybe_invalidate, - redis_params) + redis_params) redis_script_id.maybe_lock = lua_redis.load_redis_script_from_file(redis_lua_script_maybe_lock, - redis_params) + redis_params) redis_script_id.save_unlock = lua_redis.load_redis_script_from_file(redis_lua_script_save_unlock, - redis_params) + redis_params) end local function create_ann(n, nlayers, rule) - -- We ignore number of layers so far when using kann + -- We ignore number of layers so far when using kann local nhidden = math.floor(n * (rule.hidden_layer_mult or 1.0) + 1.0) local t = rspamd_kann.layer.input(n) t = rspamd_kann.transform.relu(t) @@ -146,7 +145,7 @@ local function learn_pca(inputs, max_inputs) -- scatter matrix is not filled with eigenvectors lua_util.debugm(N, 'eigenvalues: %s', eigenvals) local w = rspamd_tensor.new(2, max_inputs, #scatter_matrix[1]) - for i=1,max_inputs do + for i = 1, max_inputs do w[i] = scatter_matrix[#scatter_matrix - i + 1] end @@ -172,15 +171,19 @@ local function get_roc_thresholds(ann, inputs, outputs, alpha, beta) local a = {} local b = {} - for i=1,n do + for i = 1, n do r[i] = i end - local cmp = function(p, q) return p < q end + local cmp = function(p, q) + return p < q + end - table.sort(r, function(p, q) return cmp(x[p], x[q]) end) + table.sort(r, function(p, q) + return cmp(x[p], x[q]) + end) - for i=1,n do + for i = 1, n do a[i] = x[r[i]] b[i] = y[r[i]] end @@ -190,89 +193,89 @@ local function get_roc_thresholds(ann, inputs, outputs, alpha, beta) local function get_scores(nn, input_vectors) local scores = {} - for i=1,#inputs do + for i = 1, #inputs do local score = nn:apply1(input_vectors[i], nn.pca)[1] - scores[#scores+1] = score + scores[#scores + 1] = score end return scores end local fpr = {} - local fnr = {} - local scores = get_scores(ann, inputs) - - scores, outputs = sort_relative(scores, outputs) - - local n_samples = #outputs - local n_spam = 0 - local n_ham = 0 - local ham_count_ahead = {} - local spam_count_ahead = {} - local ham_count_behind = {} - local spam_count_behind = {} - - ham_count_ahead[n_samples + 1] = 0 - spam_count_ahead[n_samples + 1] = 0 - - for i=n_samples,1,-1 do - - if outputs[i][1] == 0 then - n_ham = n_ham + 1 - ham_count_ahead[i] = 1 - spam_count_ahead[i] = 0 - else - n_spam = n_spam + 1 - ham_count_ahead[i] = 0 - spam_count_ahead[i] = 1 - end - - ham_count_ahead[i] = ham_count_ahead[i] + ham_count_ahead[i + 1] - spam_count_ahead[i] = spam_count_ahead[i] + spam_count_ahead[i + 1] - end - - for i=1,n_samples do + local fnr = {} + local scores = get_scores(ann, inputs) + + scores, outputs = sort_relative(scores, outputs) + + local n_samples = #outputs + local n_spam = 0 + local n_ham = 0 + local ham_count_ahead = {} + local spam_count_ahead = {} + local ham_count_behind = {} + local spam_count_behind = {} + + ham_count_ahead[n_samples + 1] = 0 + spam_count_ahead[n_samples + 1] = 0 + + for i = n_samples, 1, -1 do + + if outputs[i][1] == 0 then + n_ham = n_ham + 1 + ham_count_ahead[i] = 1 + spam_count_ahead[i] = 0 + else + n_spam = n_spam + 1 + ham_count_ahead[i] = 0 + spam_count_ahead[i] = 1 + end + + ham_count_ahead[i] = ham_count_ahead[i] + ham_count_ahead[i + 1] + spam_count_ahead[i] = spam_count_ahead[i] + spam_count_ahead[i + 1] + end + + for i = 1, n_samples do if outputs[i][1] == 0 then - ham_count_behind[i] = 1 - spam_count_behind[i] = 0 - else - ham_count_behind[i] = 0 - spam_count_behind[i] = 1 - end - - if i ~= 1 then - ham_count_behind[i] = ham_count_behind[i] + ham_count_behind[i - 1] - spam_count_behind[i] = spam_count_behind[i] + spam_count_behind[i - 1] - end - end - - for i=1,n_samples do - fpr[i] = 0 - fnr[i] = 0 - - if (ham_count_ahead[i + 1] + ham_count_behind[i]) ~= 0 then - fpr[i] = ham_count_ahead[i + 1] / (ham_count_ahead[i + 1] + ham_count_behind[i]) - end - - if (spam_count_behind[i] + spam_count_ahead[i + 1]) ~= 0 then - fnr[i] = spam_count_behind[i] / (spam_count_behind[i] + spam_count_ahead[i + 1]) - end - end - - local p = n_spam / (n_spam + n_ham) - - local cost = {} - local min_cost_idx = 0 - local min_cost = math.huge - for i=1,n_samples do - cost[i] = ((1 - p) * alpha * fpr[i]) + (p * beta * fnr[i]) - if min_cost >= cost[i] then - min_cost = cost[i] - min_cost_idx = i - end - end - - return scores[min_cost_idx] + ham_count_behind[i] = 1 + spam_count_behind[i] = 0 + else + ham_count_behind[i] = 0 + spam_count_behind[i] = 1 + end + + if i ~= 1 then + ham_count_behind[i] = ham_count_behind[i] + ham_count_behind[i - 1] + spam_count_behind[i] = spam_count_behind[i] + spam_count_behind[i - 1] + end + end + + for i = 1, n_samples do + fpr[i] = 0 + fnr[i] = 0 + + if (ham_count_ahead[i + 1] + ham_count_behind[i]) ~= 0 then + fpr[i] = ham_count_ahead[i + 1] / (ham_count_ahead[i + 1] + ham_count_behind[i]) + end + + if (spam_count_behind[i] + spam_count_ahead[i + 1]) ~= 0 then + fnr[i] = spam_count_behind[i] / (spam_count_behind[i] + spam_count_ahead[i + 1]) + end + end + + local p = n_spam / (n_spam + n_ham) + + local cost = {} + local min_cost_idx = 0 + local min_cost = math.huge + for i = 1, n_samples do + cost[i] = ((1 - p) * alpha * fpr[i]) + (p * beta * fnr[i]) + if min_cost >= cost[i] then + min_cost = cost[i] + min_cost_idx = i + end + end + + return scores[min_cost_idx] end -- This function is intended to extend lock for ANN during training @@ -299,7 +302,7 @@ local function register_lock_extender(rule, set, ev_base, ann_key) true, -- is write redis_lock_extend_cb, --callback 'HINCRBY', -- command - {ann_key, 'lock', '30'} + { ann_key, 'lock', '30' } ) else lua_util.debugm(N, rspamd_config, "stop lock extension as learning_spawned is false") @@ -337,7 +340,8 @@ local function can_push_train_vector(rule, task, learn_type, nspam, nham) end end return true - else -- Enough learns + else + -- Enough learns rspamd_logger.infox(task, 'skip %s sample to keep spam/ham balance; too many spam samples: %s', learn_type, nspam) @@ -403,7 +407,7 @@ end -- Closure generator for unlock function local function gen_unlock_cb(rule, set, ann_key) - return function (err) + return function(err) if err then rspamd_logger.errx(rspamd_config, 'cannot unlock ANN %s:%s at %s from redis: %s', rule.prefix, set.name, ann_key, err) @@ -426,7 +430,7 @@ local function redis_ann_prefix(rule, settings_name) -- We also need to count metatokens: local n = meta_functions.version return string.format('%s%d_%s_%d_%s', - settings.prefix, plugin_ver, rule.prefix, n, settings_name) + settings.prefix, plugin_ver, rule.prefix, n, settings_name) end -- This function receives training vectors, checks them, spawn learning and saves ANN in Redis @@ -449,7 +453,7 @@ local function spawn_train(params) -- Used to show parsed vectors in a convenient format (for debugging only) local function debug_vec(t) local ret = {} - for i,v in ipairs(t) do + for i, v in ipairs(t) do if v ~= 0 then ret[#ret + 1] = string.format('%d=%.2f', i, v) end @@ -462,14 +466,14 @@ local function spawn_train(params) -- KANN automatically shuffles those samples -- 1.0 is used for spam and -1.0 is used for ham -- It implies that output layer can express that (e.g. tanh output) - for _,e in ipairs(params.spam_vec) do + for _, e in ipairs(params.spam_vec) do inputs[#inputs + 1] = e - outputs[#outputs + 1] = {1.0} + outputs[#outputs + 1] = { 1.0 } --rspamd_logger.debugm(N, rspamd_config, 'spam vector: %s', debug_vec(e)) end - for _,e in ipairs(params.ham_vec) do + for _, e in ipairs(params.ham_vec) do inputs[#inputs + 1] = e - outputs[#outputs + 1] = {-1.0} + outputs[#outputs + 1] = { -1.0 } --rspamd_logger.debugm(N, rspamd_config, 'ham vector: %s', debug_vec(e)) end @@ -486,7 +490,7 @@ local function spawn_train(params) rspamd_logger.errx(rspamd_config, 'ANN %s:%s: train error: observed nan in error cost!; value cost = %s', params.rule.prefix, params.set.name, value_cost) - for i,e in ipairs(inputs) do + for i, e in ipairs(inputs) do lua_util.debugm(N, rspamd_config, 'train vector %s -> %s', debug_vec(e), outputs[i][1]) end @@ -515,7 +519,7 @@ local function spawn_train(params) lua_util.debugm(N, rspamd_config, "start neural train for ANN %s:%s", params.rule.prefix, params.set.name) - local ret,err = pcall(train_ann.train1, train_ann, + local ret, err = pcall(train_ann.train1, train_ann, inputs, outputs, { lr = params.rule.train.learning_rate, max_epoch = params.rule.train.max_iterations, @@ -536,19 +540,19 @@ local function spawn_train(params) local roc_thresholds = {} if params.rule.roc_enabled then local spam_threshold = get_roc_thresholds(train_ann, - inputs, - outputs, - 1 - params.rule.roc_misclassification_cost, - params.rule.roc_misclassification_cost) + inputs, + outputs, + 1 - params.rule.roc_misclassification_cost, + params.rule.roc_misclassification_cost) local ham_threshold = get_roc_thresholds(train_ann, - inputs, - outputs, - params.rule.roc_misclassification_cost, - 1 - params.rule.roc_misclassification_cost) - roc_thresholds = {spam_threshold, ham_threshold} + inputs, + outputs, + params.rule.roc_misclassification_cost, + 1 - params.rule.roc_misclassification_cost) + roc_thresholds = { spam_threshold, ham_threshold } rspamd_logger.messagex("ROC thresholds: (spam_threshold: %s, ham_threshold: %s)", - roc_thresholds[1], roc_thresholds[2]) + roc_thresholds[1], roc_thresholds[2]) end if not seen_nan then @@ -585,7 +589,7 @@ local function spawn_train(params) false, -- is write gen_unlock_cb(params.rule, params.set, params.ann_key), --callback 'HDEL', -- command - {params.ann_key, 'lock'} + { params.ann_key, 'lock' } ) else rspamd_logger.infox(rspamd_config, 'saved ANN %s:%s to redis: %s', @@ -605,7 +609,7 @@ local function spawn_train(params) true, -- is write gen_unlock_cb(params.rule, params.set, params.ann_key), --callback 'HDEL', -- command - {params.ann_key, 'lock'} + { params.ann_key, 'lock' } ) else local parser = ucl.parser() @@ -653,17 +657,17 @@ local function spawn_train(params) params.set.ann.redis_key, params.ann_key) lua_redis.exec_redis_script(redis_script_id.save_unlock, - {ev_base = params.ev_base, is_write = true}, + { ev_base = params.ev_base, is_write = true }, redis_save_cb, - {profile.redis_key, - redis_ann_prefix(params.rule, params.set.name), - ann_data, - profile_serialized, - tostring(params.rule.ann_expire), - tostring(os.time()), - params.ann_key, -- old key to unlock... - roc_thresholds_serialized, - pca_data, + { profile.redis_key, + redis_ann_prefix(params.rule, params.set.name), + ann_data, + profile_serialized, + tostring(params.rule.ann_expire), + tostring(os.time()), + params.ann_key, -- old key to unlock... + roc_thresholds_serialized, + pca_data, }) end end @@ -672,7 +676,7 @@ local function spawn_train(params) fill_set_ann(params.set, params.ann_key) end - params.worker:spawn_process{ + params.worker:spawn_process { func = train, on_complete = ann_trained, proctitle = string.format("ANN train for %s/%s", params.rule.prefix, params.set.name), @@ -695,7 +699,9 @@ local function process_rules_settings() -- Ensure that we have an array... lua_util.debugm(N, rspamd_config, "use static profile for %s (%s): %s", rule.prefix, selt.name, profile) - if not profile[1] then profile = lua_util.keys(profile) end + if not profile[1] then + profile = lua_util.keys(profile) + end selt.symbols = profile else lua_util.debugm(N, rspamd_config, "use dynamic cfg based profile for %s (%s)", @@ -758,7 +764,7 @@ local function process_rules_settings() }) end - for k,rule in pairs(settings.rules) do + for k, rule in pairs(settings.rules) do if not rule.allowed_settings then rule.allowed_settings = {} elseif rule.allowed_settings == 'all' then @@ -788,7 +794,7 @@ local function process_rules_settings() -- Now, for each allowed settings, we store sorted symbols + digest -- We set table rule.settings[id] -> { name = name, symbols = symbols, digest = digest } - for s,_ in pairs(rule.allowed_settings) do + for s, _ in pairs(rule.allowed_settings) do -- Here, we have a name, set of symbols and local settings_id = s if type(settings_id) ~= 'number' then @@ -802,7 +808,7 @@ local function process_rules_settings() } process_settings_elt(rule, nelt) - for id,ex in pairs(rule.settings) do + for id, ex in pairs(rule.settings) do if type(ex) == 'table' then if nelt and lua_util.distance_sorted(ex.symbols, nelt.symbols) == 0 then -- Equal symbols, add reference @@ -829,7 +835,9 @@ local function get_rule_settings(task, rule) local sid = task:get_settings_id() or -1 local set = rule.settings[sid] - if not set then return nil end + if not set then + return nil + end while type(set) == 'number' do -- Reference to another settings! @@ -843,10 +851,10 @@ local function result_to_vector(task, profile) if not profile.zeros then -- Fill zeros vector local zeros = {} - for i=1,meta_functions.count_metatokens() do + for i = 1, meta_functions.count_metatokens() do zeros[i] = 0.0 end - for _,_ in ipairs(profile.symbols) do + for _, _ in ipairs(profile.symbols) do zeros[#zeros + 1] = 0.0 end profile.zeros = zeros @@ -855,7 +863,7 @@ local function result_to_vector(task, profile) local vec = lua_util.shallowcopy(profile.zeros) local mt = meta_functions.rspamd_gen_metatokens(task) - for i,v in ipairs(mt) do + for i, v in ipairs(mt) do vec[i] = v end diff --git a/lualib/plugins/rbl.lua b/lualib/plugins/rbl.lua index baa019f41..bff53f9ba 100644 --- a/lualib/plugins/rbl.lua +++ b/lualib/plugins/rbl.lua @@ -21,24 +21,24 @@ local lua_util = require "lua_util" -- Common RBL plugin definitions local check_types = { - from = { - connfilter = true, - }, - received = {}, - helo = { - connfilter = true, - }, - urls = {}, - content_urls = {}, - emails = {}, - replyto = {}, - dkim = {}, - rdns = { - connfilter = true, - }, - selector = { - require_argument = true, - }, + from = { + connfilter = true, + }, + received = {}, + helo = { + connfilter = true, + }, + urls = {}, + content_urls = {}, + emails = {}, + replyto = {}, + dkim = {}, + rdns = { + connfilter = true, + }, + selector = { + require_argument = true, + }, } local default_options = { @@ -93,8 +93,8 @@ local rule_schema_tbl = { exclude_private_ips = ts.boolean:is_optional(), exclude_users = ts.boolean:is_optional(), from = ts.boolean:is_optional(), - hash = ts.one_of{"sha1", "sha256", "sha384", "sha512", "md5", "blake2"}:is_optional(), - hash_format = ts.one_of{"hex", "base32", "base64"}:is_optional(), + hash = ts.one_of { "sha1", "sha256", "sha384", "sha512", "md5", "blake2" }:is_optional(), + hash_format = ts.one_of { "hex", "base32", "base64" }:is_optional(), hash_len = (ts.integer + ts.string / tonumber):is_optional(), helo = ts.boolean:is_optional(), ignore_default = ts.boolean:is_optional(), -- alias @@ -120,14 +120,16 @@ local rule_schema_tbl = { replyto = ts.boolean:is_optional(), requests_limit = (ts.integer + ts.string / tonumber):is_optional(), require_symbols = ( - ts.array_of(ts.string) + (ts.string / function(s) return {s} end) + ts.array_of(ts.string) + (ts.string / function(s) + return { s } + end) ):is_optional(), resolve_ip = ts.boolean:is_optional(), return_bits = return_bits_schema:is_optional(), return_codes = return_codes_schema:is_optional(), returnbits = return_bits_schema:is_optional(), returncodes = return_codes_schema:is_optional(), - selector = ts.one_of{ts.string, ts.table}:is_optional(), + selector = ts.one_of { ts.string, ts.table }:is_optional(), selector_flatten = ts.boolean:is_optional(), symbol = ts.string:is_optional(), symbols_prefixes = ts.map_of(ts.string, ts.string):is_optional(), @@ -137,7 +139,9 @@ local rule_schema_tbl = { urls = ts.boolean:is_optional(), whitelist = lua_maps.map_schema:is_optional(), whitelist_exception = ( - ts.array_of(ts.string) + (ts.string / function(s) return {s} end) + ts.array_of(ts.string) + (ts.string / function(s) + return { s } + end) ):is_optional(), checks = ts.array_of(ts.one_of(lua_util.keys(check_types))):is_optional(), exclude_checks = ts.array_of(ts.one_of(lua_util.keys(check_types))):is_optional(), @@ -148,13 +152,13 @@ local function convert_checks(rule) if rule.checks then local all_connfilter = true local exclude_checks = lua_util.list_to_hash(rule.exclude_checks or {}) - for _,check in ipairs(rule.checks) do + for _, check in ipairs(rule.checks) do if not exclude_checks[check] then local check_type = check_types[check] if check_type.require_argument then if not rule[check] then rspamd_logger.errx(rspamd_config, 'rbl rule %s has check %s which requires an argument', - rule.symbol, check) + rule.symbol, check) return nil end end @@ -167,12 +171,12 @@ local function convert_checks(rule) if not check_type then rspamd_logger.errx(rspamd_config, 'rbl rule %s has invalid check type: %s', - rule.symbol, check) + rule.symbol, check) return nil end else rspamd_logger.infox(rspamd_config, 'disable check %s in %s: excluded explicitly', - check, rule.symbol) + check, rule.symbol) end end rule.connfilter = all_connfilter @@ -180,7 +184,7 @@ local function convert_checks(rule) -- Now check if we have any check enabled at all local check_found = false - for k,_ in pairs(check_types) do + for k, _ in pairs(check_types) do if type(rule[k]) ~= 'nil' then check_found = true break @@ -199,7 +203,7 @@ end -- Add default boolean flags to the schema -for def_k,_ in pairs(default_options) do +for def_k, _ in pairs(default_options) do rule_schema_tbl[def_k:sub(#('default_') + 1)] = ts.boolean:is_optional() end |