]> source.dussan.org Git - rspamd.git/commitdiff
[Feature] Lua_mime: Add schema for message transfer
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Sat, 27 Nov 2021 14:57:20 +0000 (14:57 +0000)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Sat, 27 Nov 2021 14:58:13 +0000 (14:58 +0000)
lualib/lua_mime.lua

index f248dec7a2fe709bfec385e9390fcc3b093ef2e9..2768195bd7ef17cbe1788ef6d360ea51236139d3 100644 (file)
@@ -640,4 +640,76 @@ exports.message_to_ucl = function(task, stringify_content)
   return result
 end
 
+--[[[
+-- @function lua_mime.message_to_ucl_schema()
+-- Returns schema for a message to verify result/document fields
+--]]
+exports.message_to_ucl_schema = function()
+  local ts = require("tableshape").types
+
+  local function headers_schema()
+    return ts.shape{
+      order =  ts.integer:describe('Header order in a message'),
+      raw = ts.string:describe('Raw header value'):is_optional(),
+      empty_separator = ts.boolean:describe('Whether header has an empty separator'),
+      separator = ts.string:describe('Separator between a header and a value'),
+      decoded = ts.string:describe('Decoded value'):is_optional(),
+      value = ts.string:describe('Decoded value'):is_optional(),
+      name = ts.string:describe('Header name'),
+      tab_separated = ts.boolean:describe('Whether header has tab as a separator')
+    }
+  end
+
+  local function part_schema()
+    return ts.shape{
+      content =  ts.string:describe('Decoded content'),
+      size = ts.integer:describe('Size of the part'),
+      type = ts.string:describe('Announced type'):is_optional(),
+      detected_type = ts.string:describe('Detected type'):is_optional(),
+      boundary = ts.string:describe('Eclosing boundary'):is_optional(),
+      filename = ts.string:describe('File name for attachments'):is_optional(),
+      headers = ts.array_of(headers_schema()):describe('Part headers'),
+    }
+  end
+
+  local function email_addr_schema()
+    return ts.shape{
+      addr =  ts.string:describe('Parsed address'):is_optional(),
+      raw = ts.string:describe('Raw address'),
+      flags = ts.shape{
+        valid = ts.boolean:describe('Valid address'):is_optional(),
+        ip = ts.boolean:describe('IP like address'):is_optional(),
+        braced = ts.boolean:describe('Have braces around address'):is_optional(),
+        quoted = ts.boolean:describe('Have quotes around address'):is_optional(),
+        empty = ts.boolean:describe('Empty address'):is_optional(),
+        backslash = ts.boolean:describe('Backslash in address'):is_optional(),
+        ['8bit'] = ts.boolean:describe('8 bit characters in address'):is_optional(),
+      },
+      user =  ts.string:describe('Parsed user part'):is_optional(),
+      name =  ts.string:describe('Displayed name'):is_optional(),
+      domain =  ts.string:describe('Parsed domain part'):is_optional(),
+    }
+  end
+  local function envelope_schema()
+    return ts.shape{
+      from_smtp = email_addr_schema():describe('SMTP from'):is_optional(),
+      recipients_smtp = ts.array_of(email_addr_schema()):describe('SMTP recipients'):is_optional(),
+      helo = ts.string:describe('SMTP Helo'):is_optional(),
+      hostname = ts.string:describe('Sender hostname'):is_optional(),
+      client_ip = ts.string:describe('Client ip'):is_optional(),
+      from_ip = ts.string:describe('Sender ip'):is_optional(),
+    }
+  end
+
+  return ts.shape{
+    headers = ts.array_of(headers_schema()),
+    parts = ts.array_of(part_schema()),
+    digest = ts.pattern(string.format('^%s$', string.rep('%x', 32)))
+        :describe('Message digest'),
+    newlines = ts.one_of({"cr", "lf", "crlf"}):describe('Newlines type'),
+    size = ts.integer:describe('Size of the message in bytes'),
+    envelope = envelope_schema()
+  }
+end
+
 return exports