comparison mod_firewall/marks.lib.lua @ 5536:96dec7681af8

mod_firewall: Update user marks to store instantly via map store The original approach was to keep marks in memory only, and persist them at shutdown. That saves I/O, at the cost of potentially losing marks on an unclean shutdown. This change persists marks instantly, which may have some performance overhead but should be more "correct". It also splits the marking/unmarking into an event which may be watched or even fired by other modules.
author Matthew Wild <mwild1@gmail.com>
date Thu, 08 Jun 2023 16:20:42 +0100
parents 165d2877eeac
children 3804ee5117ca
comparison
equal deleted inserted replaced
5535:eeccec0955a1 5536:96dec7681af8
1 local mark_storage = module:open_store("firewall_marks"); 1 local mark_storage = module:open_store("firewall_marks");
2 local mark_map_storage = module:open_store("firewall_marks", "map");
2 3
3 local user_sessions = prosody.hosts[module.host].sessions; 4 local user_sessions = prosody.hosts[module.host].sessions;
4 5
5 module:hook("resource-bind", function (event) 6 module:hook("resource-bind", function (event)
6 local session = event.session; 7 local session = event.session;
12 user.firewall_marks = marks; -- luacheck: ignore 122 13 user.firewall_marks = marks; -- luacheck: ignore 122
13 end 14 end
14 session.firewall_marks = marks; 15 session.firewall_marks = marks;
15 end); 16 end);
16 17
17 module:hook("resource-unbind", function (event) 18 module:hook("firewall/marked/user", function (event)
18 local session = event.session; 19 local user = user_sessions[event.username];
19 local username = session.username; 20 local marks = user and user.firewall_marks;
20 local marks = session.firewall_marks; 21 if marks then
21 mark_storage:set(username, marks); 22 marks[event.mark] = event.timestamp;
22 end); 23 end
24 local ok, err = mark_map_storage:set(event.username, event.mark, event.timestamp);
25 if not ok then
26 module:log("error", "Failed to mark user %q with %q: %s", event.username, event.mark, err);
27 end
28 end, 1);
23 29
30 module:hook("firewall/unmarked/user", function (event)
31 local user = user_sessions[event.username];
32 local marks = user and user.firewall_marks;
33 if marks then
34 marks[event.mark] = nil;
35 end
36 local ok, err = mark_map_storage:set(event.username, event.mark, nil);
37 if not ok then
38 module:log("error", "Failed to unmark user %q with %q: %s", event.username, event.mark, err);
39 end
40 end, 1);