• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

processone / ejabberd / 1296

19 Jan 2026 11:25AM UTC coverage: 33.562% (+0.09%) from 33.468%
1296

push

github

badlop
mod_conversejs: Cosmetic change: sort paths alphabetically

0 of 4 new or added lines in 1 file covered. (0.0%)

11245 existing lines in 174 files now uncovered.

15580 of 46421 relevant lines covered (33.56%)

1074.56 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

82.05
/src/mod_antispam_rtbl.erl
1
%%%----------------------------------------------------------------------
2
%%% File    : mod_antispam_rtbl.erl
3
%%% Author  : Stefan Strigler <stefan@strigler.de>
4
%%% Purpose : Collection of RTBL specific functionality
5
%%% Created : 20 Mar 2025 by Stefan Strigler <stefan@strigler.de>
6
%%%
7
%%%
8
%%% ejabberd, Copyright (C) 2026 ProcessOne
9
%%%
10
%%% This program is free software; you can redistribute it and/or
11
%%% modify it under the terms of the GNU General Public License as
12
%%% published by the Free Software Foundation; either version 2 of the
13
%%% License, or (at your option) any later version.
14
%%%
15
%%% This program is distributed in the hope that it will be useful,
16
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
17
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18
%%% General Public License for more details.
19
%%%
20
%%% You should have received a copy of the GNU General Public License along
21
%%% with this program; if not, write to the Free Software Foundation, Inc.,
22
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23
%%%
24
%%%----------------------------------------------------------------------
25
-module(mod_antispam_rtbl).
26
-author('stefan@strigler.de').
27

28
-include_lib("xmpp/include/xmpp.hrl").
29
-include("logger.hrl").
30
-include("mod_antispam.hrl").
31

32
-define(SERVICE_MODULE, mod_antispam).
33
-define(SERVICE_JID_PREFIX, "rtbl-").
34

35
-export([parse_blocked_domains/1,
36
         parse_pubsub_event/1,
37
         pubsub_event_handler/1,
38
         request_blocked_domains/3,
39
         subscribe/3,
40
         unsubscribe/3]).
41

42
%% @format-begin
43

44
subscribe(RTBLHost, RTBLDomainsNode, From) ->
UNCOV
45
    FromJID = service_jid(From),
4✔
UNCOV
46
    SubIQ =
4✔
47
        #iq{type = set,
48
            to = jid:make(RTBLHost),
49
            from = FromJID,
50
            sub_els = [#pubsub{subscribe = #ps_subscribe{jid = FromJID, node = RTBLDomainsNode}}]},
UNCOV
51
    ?DEBUG("Sending subscription request:~n~p", [xmpp:encode(SubIQ)]),
4✔
UNCOV
52
    ejabberd_router:route_iq(SubIQ, subscribe_result, self()).
4✔
53

54
-spec unsubscribe(binary() | none, binary(), binary()) -> ok.
55
unsubscribe(none, _PSNode, _From) ->
56
    ok;
×
57
unsubscribe(RTBLHost, RTBLDomainsNode, From) ->
UNCOV
58
    FromJID = jid:make(From),
8✔
UNCOV
59
    SubIQ =
8✔
60
        #iq{type = set,
61
            to = jid:make(RTBLHost),
62
            from = FromJID,
63
            sub_els =
64
                [#pubsub{unsubscribe = #ps_unsubscribe{jid = FromJID, node = RTBLDomainsNode}}]},
UNCOV
65
    ejabberd_router:route_iq(SubIQ, unsubscribe_result, self()).
8✔
66

67
-spec request_blocked_domains(binary() | none, binary(), binary()) -> ok.
68
request_blocked_domains(none, _PSNode, _From) ->
69
    ok;
×
70
request_blocked_domains(RTBLHost, RTBLDomainsNode, From) ->
UNCOV
71
    IQ = #iq{type = get,
6✔
72
             from = jid:make(From),
73
             to = jid:make(RTBLHost),
74
             sub_els = [#pubsub{items = #ps_items{node = RTBLDomainsNode}}]},
UNCOV
75
    ?DEBUG("Requesting RTBL blocked domains from ~s:~n~p", [RTBLHost, xmpp:encode(IQ)]),
6✔
UNCOV
76
    ejabberd_router:route_iq(IQ, blocked_domains, self()).
6✔
77

78
-spec parse_blocked_domains(stanza()) -> #{binary() => any()} | undefined.
79
parse_blocked_domains(#iq{to = #jid{lserver = LServer}, type = result} = IQ) ->
UNCOV
80
    ?DEBUG("parsing iq-result items: ~p", [IQ]),
4✔
UNCOV
81
    [#rtbl_service{node = RTBLDomainsNode}] = mod_antispam:get_rtbl_services_option(LServer),
4✔
UNCOV
82
    case xmpp:get_subtag(IQ, #pubsub{}) of
4✔
83
        #pubsub{items = #ps_items{node = RTBLDomainsNode, items = Items}} ->
UNCOV
84
            ?DEBUG("Got items:~n~p", [Items]),
4✔
UNCOV
85
            parse_items(Items);
4✔
86
        _ ->
87
            undefined
×
88
    end.
89

90
-spec parse_pubsub_event(stanza()) -> #{binary() => any()}.
91
parse_pubsub_event(#message{to = #jid{lserver = LServer}} = Msg) ->
UNCOV
92
    [#rtbl_service{node = RTBLDomainsNode}] = mod_antispam:get_rtbl_services_option(LServer),
8✔
UNCOV
93
    case xmpp:get_subtag(Msg, #ps_event{}) of
8✔
94
        #ps_event{items =
95
                      #ps_items{node = RTBLDomainsNode,
96
                                items = Items,
97
                                retract = RetractIds}} ->
UNCOV
98
            maps:merge(retract_items(RetractIds), parse_items(Items));
8✔
99
        Other ->
100
            ?WARNING_MSG("Couldn't extract items: ~p", [Other]),
×
101
            #{}
×
102
    end.
103

104
-spec parse_items([ps_item()]) -> #{binary() => any()}.
105
parse_items(Items) ->
UNCOV
106
    lists:foldl(fun(#ps_item{id = ID}, Acc) ->
12✔
107
                   %% TODO extract meta/extra instructions
UNCOV
108
                   maps:put(ID, true, Acc)
12✔
109
                end,
110
                #{},
111
                Items).
112

113
-spec retract_items([binary()]) -> #{binary() => false}.
114
retract_items(Ids) ->
UNCOV
115
    lists:foldl(fun(ID, Acc) -> Acc#{ID => false} end, #{}, Ids).
8✔
116

117
-spec service_jid(binary()) -> jid().
118
service_jid(Host) ->
UNCOV
119
    jid:make(<<>>, Host, <<?SERVICE_JID_PREFIX, (ejabberd_cluster:node_id())/binary>>).
4✔
120

121
%%--------------------------------------------------------------------
122
%% Hook callbacks.
123
%%--------------------------------------------------------------------
124

125
-spec pubsub_event_handler(stanza()) -> drop | stanza().
126
pubsub_event_handler(#message{from = FromJid,
127
                              to =
128
                                  #jid{lserver = LServer,
129
                                       lresource = <<?SERVICE_JID_PREFIX, _/binary>>}} =
130
                         Msg) ->
UNCOV
131
    ?DEBUG("Got RTBL message:~n~p", [Msg]),
8✔
UNCOV
132
    From = jid:encode(FromJid),
8✔
UNCOV
133
    [#rtbl_service{host = RTBLHost}] = mod_antispam:get_rtbl_services_option(LServer),
8✔
UNCOV
134
    case RTBLHost of
8✔
135
        From ->
UNCOV
136
            ParsedItems = parse_pubsub_event(Msg),
8✔
UNCOV
137
            Proc = gen_mod:get_module_proc(LServer, ?SERVICE_MODULE),
8✔
UNCOV
138
            gen_server:cast(Proc, {update_blocked_domains, ParsedItems}),
8✔
139
            %% FIXME what's the difference between `{drop, ...}` and `{stop, {drop, ...}}`?
UNCOV
140
            drop;
8✔
141
        _Other ->
142
            ?INFO_MSG("Got unexpected message from ~s to rtbl resource:~n~p", [From, Msg]),
×
143
            Msg
×
144
    end;
145
pubsub_event_handler(Acc) ->
UNCOV
146
    ?DEBUG("unexpected something on pubsub_event_handler: ~p", [Acc]),
32✔
UNCOV
147
    Acc.
32✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc