You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

maps.lua 4.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. --[[
  2. Copyright (c) 2020, Vsevolod Stakhov <vsevolod@highsecure.ru>
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. ]]--
  13. -- Controller maps plugin
  14. local maps_cache
  15. local maps_aliases
  16. local lua_util = require "lua_util"
  17. local function maybe_fill_maps_cache()
  18. if not maps_cache then
  19. maps_cache = {}
  20. maps_aliases = {}
  21. local maps = rspamd_config:get_maps()
  22. for _,m in ipairs(maps) do
  23. -- We get the first url here and that's it
  24. local url = m:get_uri()
  25. if url ~= 'static' then
  26. if not maps_cache[url] then
  27. local alias = url:match('/([^/]+)$')
  28. maps_cache[url] = m
  29. if not maps_aliases[alias] then
  30. maps_aliases[alias] = url
  31. end
  32. else
  33. -- Do not override, as we don't care about duplicate maps that come from different
  34. -- sources.
  35. -- In theory, that should be cached but there are some exceptions even so far...
  36. url = math.random() -- to shut luacheck about empty branch with a comment
  37. end
  38. end
  39. end
  40. end
  41. end
  42. local function check_specific_map(input, uri, m, results, report_misses)
  43. local value = m:get_key(input)
  44. if value then
  45. local result = {
  46. map = uri,
  47. alias = uri:match('/([^/]+)$'),
  48. value = value,
  49. key = input,
  50. hit = true,
  51. }
  52. table.insert(results, result)
  53. elseif report_misses then
  54. local result = {
  55. map = uri,
  56. alias = uri:match('/([^/]+)$'),
  57. key = input,
  58. hit = false,
  59. }
  60. table.insert(results, result)
  61. end
  62. end
  63. local function handle_query_map(_, conn, req_params)
  64. maybe_fill_maps_cache()
  65. local keys_to_check = {}
  66. if req_params.value and req_params.value ~= '' then
  67. keys_to_check[1] = req_params.value
  68. elseif req_params.values then
  69. keys_to_check = lua_util.str_split(req_params.values, ',')
  70. end
  71. local results = {}
  72. for _,key in ipairs(keys_to_check) do
  73. for uri,m in pairs(maps_cache) do
  74. check_specific_map(key, uri, m, results, req_params.report_misses)
  75. end
  76. end
  77. conn:send_ucl{
  78. success = (#results > 0),
  79. results = results
  80. }
  81. end
  82. local function handle_query_specific_map(_, conn, req_params)
  83. maybe_fill_maps_cache()
  84. -- Fill keys to check
  85. local keys_to_check = {}
  86. if req_params.value and req_params.value ~= '' then
  87. keys_to_check[1] = req_params.value
  88. elseif req_params.values then
  89. keys_to_check = lua_util.str_split(req_params.values, ',')
  90. end
  91. local maps_to_check = maps_cache
  92. -- Fill maps to check
  93. if req_params.maps then
  94. local map_names = lua_util.str_split(req_params.maps, ',')
  95. maps_to_check = {}
  96. for _,mn in ipairs(map_names) do
  97. if maps_cache[mn] then
  98. maps_to_check[mn] = maps_cache[mn]
  99. else
  100. local alias = maps_aliases[mn]
  101. if alias then
  102. maps_to_check[alias] = maps_cache[alias]
  103. else
  104. conn:send_error(404, 'no such map: ' .. mn)
  105. end
  106. end
  107. end
  108. end
  109. local results = {}
  110. for _,key in ipairs(keys_to_check) do
  111. for uri,m in pairs(maps_to_check) do
  112. check_specific_map(key, uri, m, results, req_params.report_misses)
  113. end
  114. end
  115. conn:send_ucl{
  116. success = (#results > 0),
  117. results = results
  118. }
  119. end
  120. local function handle_list_maps(_, conn, _)
  121. maybe_fill_maps_cache()
  122. conn:send_ucl{
  123. maps = lua_util.keys(maps_cache),
  124. aliases = maps_aliases
  125. }
  126. end
  127. return {
  128. query = {
  129. handler = handle_query_map,
  130. enable = false,
  131. },
  132. query_specific = {
  133. handler = handle_query_specific_map,
  134. enable = false,
  135. },
  136. list = {
  137. handler = handle_list_maps,
  138. enable = false,
  139. },
  140. }