]> git.ipfire.org Git - thirdparty/rspamd.git/commitdiff
[Minor] Migrate lualib/plugins/rbl.lua to lua_shape
authorVsevolod Stakhov <vsevolod@rspamd.com>
Tue, 18 Nov 2025 12:05:11 +0000 (12:05 +0000)
committerVsevolod Stakhov <vsevolod@rspamd.com>
Tue, 18 Nov 2025 12:05:11 +0000 (12:05 +0000)
Replace tableshape with lua_shape in RBL plugin utilities.

Changes:
- ts.map_of(k, v) → T.table({}, {open=true, key=..., extra=...})
- ts.shape { ... } → T.table({ ... })
- ts.array_of(x) → T.array(x)
- ts.one_of { ... } → T.enum({ ... })
- ts.boolean, ts.string, ts.number → T.boolean(), T.string(), T.number()
- :is_optional() → :optional()
- Added documentation

Schemas:
- return_codes_schema: Map of symbols to IP patterns
- return_bits_schema: Map of symbols to bit numbers
- rule_schema: Complete RBL rule with 50+ configuration options

lualib/plugins/rbl.lua

index 074fc7f0cf6a50edf88a4b51c29385920faf4349..60c265d298e6c9f301a9cdf27a05fd427e74ce48 100644 (file)
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
 limitations under the License.
 ]]--
 
-local ts = require("tableshape").types
+local T = require "lua_shape.core"
 local lua_maps = require "lua_maps"
 local lua_util = require "lua_util"
 
@@ -57,97 +57,105 @@ local default_options = {
   ['default_selector_flatten'] = true,
 }
 
-local return_codes_schema = ts.map_of(
-    ts.string / string.upper, -- Symbol name
-    (
-        ts.array_of(ts.string) +
-            (ts.string / function(s)
-              return { s }
-            end) -- List of IP patterns
-    )
-)
-local return_bits_schema = ts.map_of(
-    ts.string / string.upper, -- Symbol name
-    (
-        ts.array_of(ts.number + ts.string / tonumber) +
-            (ts.string / function(s)
-              return { tonumber(s) }
-            end) +
-            (ts.number / function(s)
-              return { s }
-            end)
-    )
-)
+local return_codes_schema = T.table({}, {
+  open = true,
+  key = T.transform(T.string(), string.upper),
+  extra = T.one_of({
+    T.array(T.string()),
+    T.transform(T.string(), function(s)
+      return { s }
+    end)
+  })
+}):doc({ summary = "Map of symbol names to IP patterns" })
+
+local return_bits_schema = T.table({}, {
+  open = true,
+  key = T.transform(T.string(), string.upper),
+  extra = T.one_of({
+    T.array(T.one_of({
+      T.number(),
+      T.transform(T.string(), tonumber)
+    })),
+    T.transform(T.string(), function(s)
+      return { tonumber(s) }
+    end),
+    T.transform(T.number(), function(s)
+      return { s }
+    end)
+  })
+}):doc({ summary = "Map of symbol names to bit numbers" })
 
 local rule_schema_tbl = {
-  content_urls = ts.boolean:is_optional(),
-  disable_monitoring = ts.boolean:is_optional(),
-  disabled = ts.boolean:is_optional(),
-  dkim = ts.boolean:is_optional(),
-  dkim_domainonly = ts.boolean:is_optional(),
-  dkim_match_from = ts.boolean:is_optional(),
-  emails = ts.boolean:is_optional(),
-  emails_delimiter = ts.string:is_optional(),
-  emails_domainonly = ts.boolean:is_optional(),
-  enabled = ts.boolean:is_optional(),
-  exclude_local = 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_len = (ts.integer + ts.string / tonumber):is_optional(),
-  helo = ts.boolean:is_optional(),
-  ignore_default = ts.boolean:is_optional(), -- alias
-  ignore_defaults = ts.boolean:is_optional(),
-  ignore_url_whitelist = ts.boolean:is_optional(),
-  ignore_whitelist = ts.boolean:is_optional(),
-  ignore_whitelists = ts.boolean:is_optional(), -- alias
-  images = ts.boolean:is_optional(),
-  ipv4 = ts.boolean:is_optional(),
-  ipv6 = ts.boolean:is_optional(),
-  is_whitelist = ts.boolean:is_optional(),
-  local_exclude_ip_map = ts.string:is_optional(),
-  monitored_address = ts.string:is_optional(),
-  no_ip = ts.boolean:is_optional(),
-  process_script = ts.string:is_optional(),
-  random_monitored = ts.boolean:is_optional(),
-  rbl = ts.string,
-  rdns = ts.boolean:is_optional(),
-  received = ts.boolean:is_optional(),
-  received_flags = ts.array_of(ts.string):is_optional(),
-  received_max_pos = ts.number:is_optional(),
-  received_min_pos = ts.number:is_optional(),
-  received_nflags = ts.array_of(ts.string):is_optional(),
-  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)
-  ):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(),
-  returncodes_matcher = ts.one_of { "equality", "glob", "luapattern", "radix", "regexp" }: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(),
-  unknown = ts.boolean:is_optional(),
-  url_compose_map = lua_maps.map_schema:is_optional(),
-  url_full_hostname = ts.boolean:is_optional(),
-  url_whitelist = lua_maps.map_schema:is_optional(),
-  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)
-  ):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(),
+  content_urls = T.boolean():optional(),
+  disable_monitoring = T.boolean():optional(),
+  disabled = T.boolean():optional(),
+  dkim = T.boolean():optional(),
+  dkim_domainonly = T.boolean():optional(),
+  dkim_match_from = T.boolean():optional(),
+  emails = T.boolean():optional(),
+  emails_delimiter = T.string():optional(),
+  emails_domainonly = T.boolean():optional(),
+  enabled = T.boolean():optional(),
+  exclude_local = T.boolean():optional(),
+  exclude_users = T.boolean():optional(),
+  from = T.boolean():optional(),
+  hash = T.enum({ "sha1", "sha256", "sha384", "sha512", "md5", "blake2" }):optional(),
+  hash_format = T.enum({ "hex", "base32", "base64" }):optional(),
+  hash_len = T.one_of({ T.integer(), T.transform(T.string(), tonumber) }):optional(),
+  helo = T.boolean():optional(),
+  ignore_default = T.boolean():optional(),
+  ignore_defaults = T.boolean():optional(),
+  ignore_url_whitelist = T.boolean():optional(),
+  ignore_whitelist = T.boolean():optional(),
+  ignore_whitelists = T.boolean():optional(),
+  images = T.boolean():optional(),
+  ipv4 = T.boolean():optional(),
+  ipv6 = T.boolean():optional(),
+  is_whitelist = T.boolean():optional(),
+  local_exclude_ip_map = T.string():optional(),
+  monitored_address = T.string():optional(),
+  no_ip = T.boolean():optional(),
+  process_script = T.string():optional(),
+  random_monitored = T.boolean():optional(),
+  rbl = T.string(),
+  rdns = T.boolean():optional(),
+  received = T.boolean():optional(),
+  received_flags = T.array(T.string()):optional(),
+  received_max_pos = T.number():optional(),
+  received_min_pos = T.number():optional(),
+  received_nflags = T.array(T.string()):optional(),
+  replyto = T.boolean():optional(),
+  requests_limit = T.one_of({ T.integer(), T.transform(T.string(), tonumber) }):optional(),
+  require_symbols = T.one_of({
+    T.array(T.string()),
+    T.transform(T.string(), function(s)
+      return { s }
+    end)
+  }):optional(),
+  resolve_ip = T.boolean():optional(),
+  return_bits = return_bits_schema:optional(),
+  return_codes = return_codes_schema:optional(),
+  returnbits = return_bits_schema:optional(),
+  returncodes = return_codes_schema:optional(),
+  returncodes_matcher = T.enum({ "equality", "glob", "luapattern", "radix", "regexp" }):optional(),
+  selector = T.one_of({ { name = "string", schema = T.string() }, { name = "table", schema = T.table({}, { open = true }) } }):optional(),
+  selector_flatten = T.boolean():optional(),
+  symbol = T.string():optional(),
+  symbols_prefixes = T.table({}, { open = true, extra = T.string() }):optional(),
+  unknown = T.boolean():optional(),
+  url_compose_map = lua_maps.map_schema:optional(),
+  url_full_hostname = T.boolean():optional(),
+  url_whitelist = lua_maps.map_schema:optional(),
+  urls = T.boolean():optional(),
+  whitelist = lua_maps.map_schema:optional(),
+  whitelist_exception = T.one_of({
+    T.array(T.string()),
+    T.transform(T.string(), function(s)
+      return { s }
+    end)
+  }):optional(),
+  checks = T.array(T.enum(lua_util.keys(check_types))):optional(),
+  exclude_checks = T.array(T.enum(lua_util.keys(check_types))):optional(),
 }
 
 local function convert_checks(rule, name)
@@ -222,12 +230,12 @@ end
 
 -- Add default boolean flags to the schema
 for def_k, _ in pairs(default_options) do
-  rule_schema_tbl[def_k:sub(#('default_') + 1)] = ts.boolean:is_optional()
+  rule_schema_tbl[def_k:sub(#('default_') + 1)] = T.boolean():optional()
 end
 
 return {
   check_types = check_types,
-  rule_schema = ts.shape(rule_schema_tbl),
+  rule_schema = T.table(rule_schema_tbl):doc({ summary = "RBL rule configuration schema" }),
   default_options = default_options,
   convert_checks = convert_checks,
 }