From: Vsevolod Stakhov Date: Sat, 27 Nov 2021 14:57:20 +0000 (+0000) Subject: [Feature] Lua_mime: Add schema for message transfer X-Git-Tag: 3.2~221 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=a81b484689121941ccd379a1c2f8c6b16b2f79bd;p=rspamd.git [Feature] Lua_mime: Add schema for message transfer --- diff --git a/lualib/lua_mime.lua b/lualib/lua_mime.lua index f248dec7a..2768195bd 100644 --- a/lualib/lua_mime.lua +++ b/lualib/lua_mime.lua @@ -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