# HG changeset patch # User Matthew Wild # Date 1478263571 0 # Node ID 6848297cf40ac6c84ccaae857ab5af8206d664cd # Parent 52dd2a51dac888d3a66ea7ac7055bb5b5ff33e6d mod_firewall: Add conditions for testing whether a sender of a stanza is in the recipient's roster (or in a certain roster group) diff -r 52dd2a51dac8 -r 6848297cf40a mod_firewall/README.markdown --- a/mod_firewall/README.markdown Wed Nov 02 20:42:27 2016 +0100 +++ b/mod_firewall/README.markdown Fri Nov 04 12:46:11 2016 +0000 @@ -204,6 +204,27 @@ stanza. It is not advisable to perform access control or similar rules on JIDs in these chains (see the chain documentation for more info). +### Roster + +These functions access the roster of the recipient (only). Therefore they cannot (currently) +be used in some chains, such as for outgoing messages (the recipient may be on another server). + +Performance note: this check can potentially cause storage access (especially if the recipient +is currently offline), so you may want to limit its use in high-traffic situations, and place +it below other checks (such as a rate limiter). + +#### IN_ROSTER + +Tests whether the sender is in the recipient's roster. + + IN_ROSTER: yes + +#### IN_ROSTER_GROUP + +Tests whether the sender is in the recipient's roster, and in the named group. + + IN_ROSTER_GROUP: Friends + ### Time and date #### TIME diff -r 52dd2a51dac8 -r 6848297cf40a mod_firewall/conditions.lib.lua --- a/mod_firewall/conditions.lib.lua Wed Nov 02 20:42:27 2016 +0100 +++ b/mod_firewall/conditions.lib.lua Fri Nov 04 12:46:11 2016 +0000 @@ -3,6 +3,12 @@ local jid = require "util.jid"; +-- Helper to convert user-input strings (yes/true//no/false) to a bool +local function string_to_boolean(s) + s = s:lower(); + return s == "yes" or s == "true"; +end + -- Return a code string for a condition that checks whether the contents -- of variable with the name 'name' matches any of the values in the -- comma/space/pipe delimited list 'values'. @@ -90,6 +96,15 @@ return zone_check(zone, "from"); end +function condition_handlers.IN_ROSTER(yes_no) + local in_roster_requirement = string_to_boolean(yes_no); + return "not "..(in_roster_requirement and "not" or "").." roster_entry", { "roster_entry" }; +end + +function condition_handlers.IN_ROSTER_GROUP(group) + return ("not not (roster_entry and roster_entry.groups[%q])"):format(group), { "roster_entry" }; +end + function condition_handlers.PAYLOAD(payload_ns) return ("stanza:get_child(nil, %q)"):format(payload_ns); end diff -r 52dd2a51dac8 -r 6848297cf40a mod_firewall/mod_firewall.lua --- a/mod_firewall/mod_firewall.lua Wed Nov 02 20:42:27 2016 +0100 +++ b/mod_firewall/mod_firewall.lua Fri Nov 04 12:46:11 2016 +0000 @@ -123,6 +123,11 @@ return ("local multi_throttle_%s = rates.%s:multi();"):format(throttle, throttle); end; }; + roster_entry = { + global_code = [[local rostermanager = require "core.rostermanager";]]; + local_code = [[local roster_entry = (rostermanager.load_roster(to_node, to_host) or {})[bare_from];]]; + depends = { "split_to", "bare_from" }; + } }; local function include_dep(dependency, code)