Browse Source

Start lua-settings implementation.

tags/0.7.0
Vsevolod Stakhov 9 years ago
parent
commit
0d2d40e882
1 changed files with 209 additions and 0 deletions
  1. 209
    0
      src/plugins/lua/settings.lua

+ 209
- 0
src/plugins/lua/settings.lua View File

@@ -0,0 +1,209 @@
-- This plugin implements user dynamic settings
-- Settings documentation can be found here:
-- https://rspamd.com/doc/configuration/settings.html

local set_section = rspamd_config:get_key("settings")
local settings = {}

-- Functional utilities
local function filter(func, tbl)
local newtbl= {}
for i,v in pairs(tbl) do
if func(v) then
newtbl[i]=v
end
end
return newtbl
end

-- Check limit for a task
local function check_settings(task)

end

-- Process settings based on their priority
local function process_settings_table(tbl)
local get_priority = function(elt)
local pri_tonum = function(p)
if p then
if type(p) == "number" then
return tonumber(p)
elseif type(p) == "string" then
if p == "high" then
return 3
elseif p == "medium" then
return 2
end
end
end
return 1
end
return pri_tonum(elt['priority'])
end
-- Check the setting element internal data
local process_setting_elt = function(elt)
-- Process IP address
local function process_ip(ip)
local out = {}
if type(ip) == "table" then
for i,v in ipairs(ip) do
table.insert(out, process_ip(v))
end
elseif type(ip) == "string" then
local slash = string.find(ip, '/')
if not slash then
-- Just a plain IP address
local res = rspamd_ip.from_string(ip)
if res:is_valid() then
table.insert(out, {res, 0})
else
rspamd_logger.err("bad IP address: " .. ip)
return nil
end
else
local res = rspamd_ip.from_string(string.sub(ip, 1, slash))
local mask = tonumber(string.sub(ip, slash + 1))
if res:is_valid() then
table.insert(out, {res, mask})
else
rspamd_logger.err("bad IP address: " .. ip)
return nil
end
end
else
return nil
end
return out
end
local process_addr = function(addr)
local out = {
name = {},
user = {},
domain = {},
regexp = {}
}
if type(addr) == "table" then
for i,v in ipairs(addr) do
table.insert(out, process_addr(v))
end
elseif type(addr) == "string" then
if addr[1] == '/' then
-- It is a regexp
local re = rspamd_regexp.create(string.sub(addr, 2))
if re then
out['regexp'] = re
setmetatable(out, {
__gc = function(t) t['regexp']:destroy() end
})
else
rspamd_logger.err("bad regexp: " .. addr)
end
elseif addr[1] == '@' then
-- It is a domain if form @domain
out['domain'] = string.sub(addr, 2)
else
-- Check user@domain parts
local at = string.find(addr, '@')
if at then
-- It is full address
out['name'] = addr
else
-- It is a user
out['user'] = addr
end
end
else
return nil
end
return out
end
local out = {
ip = {},
rcpt = {},
from = {}
}
if elt['ip'] then
local ip = process_ip(elt['ip'])
if ip then
table.insert(out['ip'], ip)
end
end
if elt['from'] then
local from = process_addr(elt['from'])
if from then
table.insert(out['from'], from)
end
end
if elt['rcpt'] then
local rcpt = process_addr(elt['rcpt'])
if rcpt then
table.insert(out['rcpt'], rcpt)
end
end
return out
end
-- filter trash in the input
local ft = filter(
function(elt)
if type(elt) == "table" then
return true
end
return false
end, tbl)
-- clear all settings
for k,v in pairs(settings) do settings[k]=nil end
-- fill new settings by priority
for k,v in pairs(ft) do
local pri = get_priority(v)
if not settings[pri] then
settings[pri] = {}
end
local s = process_setting_elt(v)
if s then
settings[pri][k] = s
end
end
end

-- Parse settings map from the ucl line
local function process_settings_map(string)
local ucl_parser = require "ucl.parser"
local res,err = ucl_parser:parse_string(string)
if not res then
rspamd_log.warn('cannot parse settings map: ' .. err)
else
process_settings_table(res)
end
end

if type(set_section) == "string" then
-- Just a map of ucl
if rspamd_config:add_map(set_section, process_settings_map) then
rspamd_config:register_pre_filter(check_settings)
end
elseif type(set_section) == "table" then
if process_settings_table(set_section) then
rspamd_config:register_pre_filter(check_settings)
end
end

Loading…
Cancel
Save