2019-04-08 14:06:19 +02:00
|
|
|
--[[
|
|
|
|
Copyright (c) 2019, Vsevolod Stakhov <vsevolod@highsecure.ru>
|
|
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
you may not use this file except in compliance with the License.
|
|
|
|
You may obtain a copy of the License at
|
|
|
|
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
See the License for the specific language governing permissions and
|
|
|
|
limitations under the License.
|
|
|
|
]]--
|
|
|
|
|
|
|
|
local l = require 'lpeg'
|
2019-11-26 18:29:42 +01:00
|
|
|
local lua_util = require "lua_util"
|
|
|
|
local N = "lua_content"
|
2019-04-08 14:06:19 +02:00
|
|
|
|
2019-11-25 14:26:17 +01:00
|
|
|
local ical_grammar
|
|
|
|
|
|
|
|
local function gen_grammar()
|
|
|
|
if not ical_grammar then
|
2020-06-29 18:17:23 +02:00
|
|
|
local wsp = l.S(" \t\v\f")
|
2021-01-13 16:18:37 +01:00
|
|
|
local crlf = (l.P"\r"^-1 * l.P"\n") + l.P"\r"
|
2019-11-25 14:26:17 +01:00
|
|
|
local eol = (crlf * #crlf) + (crlf - (crlf^-1 * wsp))
|
|
|
|
local name = l.C((l.P(1) - (l.P":"))^1) / function(v) return (v:gsub("[\n\r]+%s","")) end
|
|
|
|
local value = l.C((l.P(1) - eol)^0) / function(v) return (v:gsub("[\n\r]+%s","")) end
|
2020-06-29 18:17:23 +02:00
|
|
|
ical_grammar = name * ":" * wsp^0 * value * eol^-1
|
2019-11-25 14:26:17 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
return ical_grammar
|
|
|
|
end
|
2019-04-08 14:06:19 +02:00
|
|
|
|
|
|
|
local exports = {}
|
|
|
|
|
2019-11-26 18:29:42 +01:00
|
|
|
local function extract_text_data(specific)
|
|
|
|
local fun = require "fun"
|
|
|
|
|
|
|
|
local tbl = fun.totable(fun.map(function(e) return e[2]:lower() end, specific.elts))
|
|
|
|
return table.concat(tbl, '\n')
|
|
|
|
end
|
|
|
|
|
2021-04-20 16:26:46 +02:00
|
|
|
|
|
|
|
-- Keys that can have visible urls
|
|
|
|
local url_keys = lua_util.list_to_hash{
|
|
|
|
'description',
|
|
|
|
'location',
|
|
|
|
'summary',
|
|
|
|
'organizer',
|
|
|
|
'organiser',
|
|
|
|
'attendee',
|
|
|
|
'url'
|
|
|
|
}
|
|
|
|
|
2020-07-01 14:24:01 +02:00
|
|
|
local function process_ical(input, mpart, task)
|
2019-11-26 18:29:42 +01:00
|
|
|
local control={n='\n', r=''}
|
2019-11-25 14:26:17 +01:00
|
|
|
local rspamd_url = require "rspamd_url"
|
2019-11-26 18:29:42 +01:00
|
|
|
local escaper = l.Ct((gen_grammar() / function(key, value)
|
2019-11-25 14:26:17 +01:00
|
|
|
value = value:gsub("\\(.)", control)
|
2021-04-20 16:26:46 +02:00
|
|
|
key = key:lower():match('^([^;]+)')
|
|
|
|
|
|
|
|
if key and url_keys[key] then
|
|
|
|
local local_urls = rspamd_url.all(task:get_mempool(), value)
|
|
|
|
|
|
|
|
if local_urls and #local_urls > 0 then
|
|
|
|
for _,u in ipairs(local_urls) do
|
|
|
|
lua_util.debugm(N, task, 'ical: found URL in ical key "%s": %s',
|
|
|
|
key, tostring(u))
|
|
|
|
task:inject_url(u, mpart)
|
|
|
|
end
|
2019-11-25 14:26:17 +01:00
|
|
|
end
|
|
|
|
end
|
2019-11-26 18:29:42 +01:00
|
|
|
lua_util.debugm(N, task, 'ical: ical key %s = "%s"',
|
|
|
|
key, value)
|
|
|
|
return {key, value}
|
2019-11-25 14:26:17 +01:00
|
|
|
end)^1)
|
2019-04-08 14:06:19 +02:00
|
|
|
|
2019-11-26 18:29:42 +01:00
|
|
|
local elts = escaper:match(input)
|
2019-04-08 14:06:19 +02:00
|
|
|
|
2019-11-26 18:29:42 +01:00
|
|
|
if not elts then
|
2019-04-08 14:06:19 +02:00
|
|
|
return nil
|
|
|
|
end
|
|
|
|
|
2019-11-26 18:29:42 +01:00
|
|
|
return {
|
|
|
|
tag = 'ical',
|
|
|
|
extract_text = extract_text_data,
|
|
|
|
elts = elts
|
|
|
|
}
|
2019-04-08 14:06:19 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
--[[[
|
2019-11-24 10:35:18 +01:00
|
|
|
-- @function lua_ical.process(input)
|
2019-04-08 14:06:19 +02:00
|
|
|
-- Returns all values from ical as a plain text. Names are completely ignored.
|
|
|
|
--]]
|
2019-11-24 10:35:18 +01:00
|
|
|
exports.process = process_ical
|
2019-04-08 14:06:19 +02:00
|
|
|
|
|
|
|
return exports
|