Support XEP-0191 Simple Communications Blocking (thanks to Stephan Maka)(EJAB-695)
This commit is contained in:
parent
806d5497c4
commit
82296c277a
|
@ -66,6 +66,7 @@
|
||||||
\newcommand{\module}[1]{\texttt{#1}}
|
\newcommand{\module}[1]{\texttt{#1}}
|
||||||
\newcommand{\modadhoc}{\module{mod\_adhoc}}
|
\newcommand{\modadhoc}{\module{mod\_adhoc}}
|
||||||
\newcommand{\modannounce}{\module{mod\_announce}}
|
\newcommand{\modannounce}{\module{mod\_announce}}
|
||||||
|
\newcommand{\modblocking}{\module{mod\_blocking}}
|
||||||
\newcommand{\modcaps}{\module{mod\_caps}}
|
\newcommand{\modcaps}{\module{mod\_caps}}
|
||||||
\newcommand{\modconfigure}{\module{mod\_configure}}
|
\newcommand{\modconfigure}{\module{mod\_configure}}
|
||||||
\newcommand{\moddisco}{\module{mod\_disco}}
|
\newcommand{\moddisco}{\module{mod\_disco}}
|
||||||
|
@ -2582,6 +2583,7 @@ The following table lists all modules included in \ejabberd{}.
|
||||||
\hline
|
\hline
|
||||||
\hline \modadhoc{} & Ad-Hoc Commands (\xepref{0050}) & \\
|
\hline \modadhoc{} & Ad-Hoc Commands (\xepref{0050}) & \\
|
||||||
\hline \ahrefloc{modannounce}{\modannounce{}} & Manage announcements & recommends \modadhoc{} \\
|
\hline \ahrefloc{modannounce}{\modannounce{}} & Manage announcements & recommends \modadhoc{} \\
|
||||||
|
\hline \modblocking{} & Simple Communications Blocking (\xepref{0191}) & \modprivacy{} \\
|
||||||
\hline \modcaps{} & Entity Capabilities (\xepref{0115}) & \\
|
\hline \modcaps{} & Entity Capabilities (\xepref{0115}) & \\
|
||||||
\hline \modconfigure{} & Server configuration using Ad-Hoc & \modadhoc{} \\
|
\hline \modconfigure{} & Server configuration using Ad-Hoc & \modadhoc{} \\
|
||||||
\hline \ahrefloc{moddisco}{\moddisco{}} & Service Discovery (\xepref{0030}) & \\
|
\hline \ahrefloc{moddisco}{\moddisco{}} & Service Discovery (\xepref{0030}) & \\
|
||||||
|
|
|
@ -513,6 +513,7 @@
|
||||||
[
|
[
|
||||||
{mod_adhoc, []},
|
{mod_adhoc, []},
|
||||||
{mod_announce, [{access, announce}]}, % recommends mod_adhoc
|
{mod_announce, [{access, announce}]}, % recommends mod_adhoc
|
||||||
|
{mod_blocking,[]}, % requires mod_privacy
|
||||||
{mod_caps, []}, % 1 proc/host
|
{mod_caps, []}, % 1 proc/host
|
||||||
{mod_configure,[]}, % requires mod_adhoc
|
{mod_configure,[]}, % requires mod_adhoc
|
||||||
{mod_disco, []},
|
{mod_disco, []},
|
||||||
|
|
|
@ -1077,7 +1077,9 @@ session_established2(El, StateData) ->
|
||||||
end;
|
end;
|
||||||
#xmlel{ns = ?NS_JABBER_CLIENT, name = 'iq'} ->
|
#xmlel{ns = ?NS_JABBER_CLIENT, name = 'iq'} ->
|
||||||
case exmpp_iq:xmlel_to_iq(El) of
|
case exmpp_iq:xmlel_to_iq(El) of
|
||||||
#iq{kind = request, ns = ?NS_PRIVACY} = IQ_Rec ->
|
#iq{kind = request, ns = Xmlns} = IQ_Rec
|
||||||
|
when Xmlns == ?NS_PRIVACY;
|
||||||
|
Xmlns == ?NS_BLOCKING ->
|
||||||
process_privacy_iq(
|
process_privacy_iq(
|
||||||
FromJID, ToJID, IQ_Rec, StateData);
|
FromJID, ToJID, IQ_Rec, StateData);
|
||||||
_ ->
|
_ ->
|
||||||
|
@ -1342,6 +1344,13 @@ handle_info({route, From, To, Packet}, StateName, StateData) ->
|
||||||
send_element(StateData, PrivPushEl),
|
send_element(StateData, PrivPushEl),
|
||||||
{false, Attrs, StateData#state{privacy_list = NewPL}}
|
{false, Attrs, StateData#state{privacy_list = NewPL}}
|
||||||
end;
|
end;
|
||||||
|
blocking ->
|
||||||
|
CDataString = exmpp_xml:get_cdata_as_list(Packet),
|
||||||
|
{ok, A2, _} = erl_scan:string(CDataString),
|
||||||
|
{_, W} = erl_parse:parse_exprs(A2),
|
||||||
|
{value, What, []} = erl_eval:exprs(W, []),
|
||||||
|
route_blocking(What, StateData),
|
||||||
|
{false, Attrs, StateData};
|
||||||
_ ->
|
_ ->
|
||||||
{false, Attrs, StateData}
|
{false, Attrs, StateData}
|
||||||
end;
|
end;
|
||||||
|
@ -2274,6 +2283,35 @@ bounce_messages() ->
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
||||||
|
%%%----------------------------------------------------------------------
|
||||||
|
%%% XEP-0191
|
||||||
|
%%%----------------------------------------------------------------------
|
||||||
|
|
||||||
|
route_blocking(What, StateData) ->
|
||||||
|
SubEl =
|
||||||
|
case What of
|
||||||
|
{Action, JIDs} when (Action == block) or (Action == unblock) ->
|
||||||
|
UnblockJids =
|
||||||
|
lists:map(
|
||||||
|
fun(JidString) ->
|
||||||
|
exmpp_xml:set_attribute(#xmlel{ns = ?NS_BLOCKING,
|
||||||
|
name = item},
|
||||||
|
<<"jid">>,
|
||||||
|
JidString)
|
||||||
|
end, JIDs),
|
||||||
|
#xmlel{ns = ?NS_BLOCKING, name = Action,
|
||||||
|
children = UnblockJids};
|
||||||
|
unblock_all ->
|
||||||
|
#xmlel{ns = ?NS_BLOCKING, name = 'unblock'}
|
||||||
|
end,
|
||||||
|
El1 = exmpp_iq:set(?NS_BLOCKING, SubEl, random),
|
||||||
|
El2 = exmpp_stanza:set_sender(El1, exmpp_jid:bare(StateData#state.jid)),
|
||||||
|
El3 = exmpp_stanza:set_recipient(El2, StateData#state.jid),
|
||||||
|
send_element(StateData, El3),
|
||||||
|
%% No need to replace active privacy list here,
|
||||||
|
%% blocking pushes are always accompanied by
|
||||||
|
%% Privacy List pushes
|
||||||
|
ok.
|
||||||
|
|
||||||
%%%----------------------------------------------------------------------
|
%%%----------------------------------------------------------------------
|
||||||
%%% JID Set memory footprint reduction code
|
%%% JID Set memory footprint reduction code
|
||||||
|
|
|
@ -0,0 +1,349 @@
|
||||||
|
%%%----------------------------------------------------------------------
|
||||||
|
%%% File : mod_blocking.erl
|
||||||
|
%%% Author : Stephan Maka
|
||||||
|
%%% Purpose : XEP-0191: Simple Communications Blocking
|
||||||
|
%%% Created : 24 Aug 2008 by Stephan Maka <stephan@spaceboyz.net>
|
||||||
|
%%%
|
||||||
|
%%%
|
||||||
|
%%% ejabberd, Copyright (C) 2002-2011 ProcessOne
|
||||||
|
%%%
|
||||||
|
%%% This program is free software; you can redistribute it and/or
|
||||||
|
%%% modify it under the terms of the GNU General Public License as
|
||||||
|
%%% published by the Free Software Foundation; either version 2 of the
|
||||||
|
%%% License, or (at your option) any later version.
|
||||||
|
%%%
|
||||||
|
%%% This program is distributed in the hope that it will be useful,
|
||||||
|
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
%%% General Public License for more details.
|
||||||
|
%%%
|
||||||
|
%%% You should have received a copy of the GNU General Public License
|
||||||
|
%%% along with this program; if not, write to the Free Software
|
||||||
|
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||||
|
%%% 02111-1307 USA
|
||||||
|
%%%
|
||||||
|
%%%----------------------------------------------------------------------
|
||||||
|
|
||||||
|
-module(mod_blocking).
|
||||||
|
|
||||||
|
-behaviour(gen_mod).
|
||||||
|
|
||||||
|
-export([start/2, stop/1,
|
||||||
|
process_iq/3,
|
||||||
|
process_iq_set/4,
|
||||||
|
process_iq_get/5]).
|
||||||
|
|
||||||
|
-include("ejabberd.hrl").
|
||||||
|
-include("jlib.hrl").
|
||||||
|
-include_lib("exmpp/include/exmpp.hrl").
|
||||||
|
-include("mod_privacy.hrl").
|
||||||
|
|
||||||
|
start(Host, Opts) ->
|
||||||
|
HostB = list_to_binary(Host),
|
||||||
|
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
|
||||||
|
ejabberd_hooks:add(privacy_iq_get, HostB,
|
||||||
|
?MODULE, process_iq_get, 40),
|
||||||
|
ejabberd_hooks:add(privacy_iq_set, HostB,
|
||||||
|
?MODULE, process_iq_set, 40),
|
||||||
|
mod_disco:register_feature(HostB, ?NS_BLOCKING),
|
||||||
|
gen_iq_handler:add_iq_handler(ejabberd_sm, HostB, ?NS_BLOCKING,
|
||||||
|
?MODULE, process_iq, IQDisc).
|
||||||
|
|
||||||
|
stop(Host) ->
|
||||||
|
HostB = list_to_binary(Host),
|
||||||
|
ejabberd_hooks:delete(privacy_iq_get, HostB,
|
||||||
|
?MODULE, process_iq_get, 40),
|
||||||
|
ejabberd_hooks:delete(privacy_iq_set, HostB,
|
||||||
|
?MODULE, process_iq_set, 40),
|
||||||
|
mod_disco:unregister_feature(HostB, ?NS_BLOCKING),
|
||||||
|
gen_iq_handler:remove_iq_handler(ejabberd_sm, HostB, ?NS_BLOCKING).
|
||||||
|
|
||||||
|
process_iq(_From, _To, IQ_Rec) ->
|
||||||
|
exmpp_iq:error(IQ_Rec, 'not-allowed').
|
||||||
|
|
||||||
|
process_iq_get(_, From, _To, #iq{ns = ?NS_BLOCKING, payload = SubEl}, _) ->
|
||||||
|
case SubEl#xmlel.name == blocklist of
|
||||||
|
true ->
|
||||||
|
LUser = exmpp_jid:prep_node(From),
|
||||||
|
LServer = exmpp_jid:prep_domain(From),
|
||||||
|
process_blocklist_get(LUser, LServer);
|
||||||
|
false ->
|
||||||
|
{error, 'bad-request'}
|
||||||
|
end;
|
||||||
|
|
||||||
|
process_iq_get(Acc, _, _, _, _) ->
|
||||||
|
Acc.
|
||||||
|
|
||||||
|
process_iq_set(_, From, _To, #iq{ns = ?NS_BLOCKING,
|
||||||
|
payload = #xmlel{name = SubElName,
|
||||||
|
children = SubEls}}) ->
|
||||||
|
LUser = exmpp_jid:prep_node(From),
|
||||||
|
LServer = exmpp_jid:prep_domain(From),
|
||||||
|
case {SubElName, exmpp_xml:remove_cdata_from_list(SubEls)} of
|
||||||
|
{block, []} ->
|
||||||
|
{error, 'bad-request'};
|
||||||
|
{block, Els} ->
|
||||||
|
JIDs = parse_blocklist_items(Els, []),
|
||||||
|
process_blocklist_block(LUser, LServer, JIDs);
|
||||||
|
{unblock, []} ->
|
||||||
|
process_blocklist_unblock_all(LUser, LServer);
|
||||||
|
{unblock, Els} ->
|
||||||
|
JIDs = parse_blocklist_items(Els, []),
|
||||||
|
process_blocklist_unblock(LUser, LServer, JIDs);
|
||||||
|
_ ->
|
||||||
|
{error, 'bad-request'}
|
||||||
|
end;
|
||||||
|
|
||||||
|
process_iq_set(Acc, _, _, _) ->
|
||||||
|
Acc.
|
||||||
|
|
||||||
|
is_list_needdb(Items) ->
|
||||||
|
lists:any(
|
||||||
|
fun(X) ->
|
||||||
|
case X#listitem.type of
|
||||||
|
subscription -> true;
|
||||||
|
group -> true;
|
||||||
|
_ -> false
|
||||||
|
end
|
||||||
|
end, Items).
|
||||||
|
|
||||||
|
get_list_blocklist_jids(LUser, LServer, Name) ->
|
||||||
|
Tuples = gen_storage:dirty_select(LServer, privacy_list_data,
|
||||||
|
[{'=', user_host, {LUser, LServer}},
|
||||||
|
{'=', name, Name},
|
||||||
|
{'=', type, jid}]),
|
||||||
|
[Tuple#privacy_list_data.value ||
|
||||||
|
Tuple <- Tuples, Tuple#privacy_list_data.match_all == true].
|
||||||
|
|
||||||
|
parse_blocklist_items([], JIDs) ->
|
||||||
|
JIDs;
|
||||||
|
|
||||||
|
parse_blocklist_items([#xmlel{name = item} = El | Els], JIDs) ->
|
||||||
|
case exmpp_xml:get_attribute(El, <<"jid">>, false) of
|
||||||
|
false ->
|
||||||
|
%% Tolerate missing jid attribute
|
||||||
|
parse_blocklist_items(Els, JIDs);
|
||||||
|
JID1 ->
|
||||||
|
JID = exmpp_jid:to_binary(exmpp_jid:parse(JID1)),
|
||||||
|
parse_blocklist_items(Els, [JID | JIDs])
|
||||||
|
end;
|
||||||
|
|
||||||
|
parse_blocklist_items([_ | Els], JIDs) ->
|
||||||
|
%% Tolerate unknown elements
|
||||||
|
parse_blocklist_items(Els, JIDs).
|
||||||
|
|
||||||
|
process_blocklist_block(LUser, LServer, JIDs) ->
|
||||||
|
F =
|
||||||
|
fun() ->
|
||||||
|
case gen_storage:read(LServer, {privacy_list, {LUser, LServer}}) of
|
||||||
|
[] ->
|
||||||
|
%% No lists yet
|
||||||
|
%% TODO: i18n here:
|
||||||
|
Default = <<"Blocked contacts">>,
|
||||||
|
gen_storage:write(LServer,
|
||||||
|
#privacy_list{
|
||||||
|
user_host = {LUser, LServer},
|
||||||
|
name = Default}),
|
||||||
|
gen_storage:write(LServer,
|
||||||
|
#privacy_default_list{
|
||||||
|
user_host = {LUser, LServer},
|
||||||
|
name = Default}),
|
||||||
|
ok;
|
||||||
|
_Lists ->
|
||||||
|
case gen_storage:read(LServer,
|
||||||
|
{privacy_default_list, {LUser, LServer}}) of
|
||||||
|
[#privacy_default_list{name = Default}] ->
|
||||||
|
%% Default list exists
|
||||||
|
Default;
|
||||||
|
[] ->
|
||||||
|
%% No default list yet, create one
|
||||||
|
%% TODO: i18n here:
|
||||||
|
Default = <<"Blocked contacts">>,
|
||||||
|
gen_storage:write(LServer,
|
||||||
|
#privacy_list{
|
||||||
|
user_host = {LUser, LServer},
|
||||||
|
name = Default}),
|
||||||
|
gen_storage:write(LServer,
|
||||||
|
#privacy_default_list{
|
||||||
|
user_host = {LUser, LServer},
|
||||||
|
name = Default})
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
AlreadyBlocked = get_list_blocklist_jids(LUser, LServer, Default),
|
||||||
|
NewItems = lists:foldr(fun(JID, Res) ->
|
||||||
|
case lists:member(JID, AlreadyBlocked) of
|
||||||
|
true ->
|
||||||
|
Res;
|
||||||
|
false ->
|
||||||
|
Data = #privacy_list_data{
|
||||||
|
user_host = {LUser, LServer},
|
||||||
|
name = Default,
|
||||||
|
type = jid,
|
||||||
|
value = JID,
|
||||||
|
action = deny,
|
||||||
|
order = 0,
|
||||||
|
match_all = true
|
||||||
|
},
|
||||||
|
gen_storage:write(LServer, Data),
|
||||||
|
[Data | Res]
|
||||||
|
end
|
||||||
|
end, [], JIDs),
|
||||||
|
{ok, Default, NewItems}
|
||||||
|
end,
|
||||||
|
case gen_storage:transaction(LServer, privacy_list_data, F) of
|
||||||
|
{atomic, {error, _} = Error} ->
|
||||||
|
Error;
|
||||||
|
{atomic, {ok, Default, Data}} ->
|
||||||
|
%% Data = gen_storage:select(LServer, privacy_list_data,
|
||||||
|
%% [{'=', user_host, {LUser, LServer}},
|
||||||
|
%% {'=', name, Default}]),
|
||||||
|
List = list_data_to_items(Data),
|
||||||
|
broadcast_list_update(LUser, LServer, Default, List),
|
||||||
|
broadcast_blocklist_event(LUser, LServer, {block, JIDs}),
|
||||||
|
{result, []};
|
||||||
|
Error ->
|
||||||
|
?DEBUG("Error ~n~p", [Error]),
|
||||||
|
{error, 'internal-server-error'}
|
||||||
|
end.
|
||||||
|
|
||||||
|
%%Copied from mod_privacy
|
||||||
|
%% storage representation to ejabberd representation
|
||||||
|
list_data_to_items(Data) ->
|
||||||
|
List =
|
||||||
|
lists:map(
|
||||||
|
fun(Data1) ->
|
||||||
|
#listitem{type = Data1#privacy_list_data.type,
|
||||||
|
value = Data1#privacy_list_data.value,
|
||||||
|
action = Data1#privacy_list_data.action,
|
||||||
|
order = Data1#privacy_list_data.order,
|
||||||
|
match_all = Data1#privacy_list_data.match_all,
|
||||||
|
match_iq = Data1#privacy_list_data.match_iq,
|
||||||
|
match_message = Data1#privacy_list_data.match_message,
|
||||||
|
match_presence_in = Data1#privacy_list_data.match_presence_in,
|
||||||
|
match_presence_out = Data1#privacy_list_data.match_presence_out}
|
||||||
|
end, Data),
|
||||||
|
SortedList = lists:keysort(#listitem.order, List),
|
||||||
|
SortedList.
|
||||||
|
|
||||||
|
process_blocklist_unblock_all(LUser, LServer) ->
|
||||||
|
F =
|
||||||
|
fun() ->
|
||||||
|
case gen_storage:read(LServer, {privacy_list, {LUser, LServer}}) of
|
||||||
|
[] ->
|
||||||
|
%% No lists, nothing to unblock
|
||||||
|
ok;
|
||||||
|
_ ->
|
||||||
|
case gen_storage:read(LServer, {privacy_default_list, {LUser, LServer}}) of
|
||||||
|
[#privacy_default_list{name = Default}] ->
|
||||||
|
%% Default list, remove all deny items
|
||||||
|
gen_storage:delete_where(LServer, privacy_list_data,
|
||||||
|
[{'=', user_host, {LUser, LServer}},
|
||||||
|
{'=', name, Default},
|
||||||
|
{'=', action, deny},
|
||||||
|
{'=', match_all, true},
|
||||||
|
{'=', type, jid}]),
|
||||||
|
Data = gen_storage:select(LServer, privacy_list_data,
|
||||||
|
[{'=', user_host, {LUser, LServer}},
|
||||||
|
{'=', name, Default}]),
|
||||||
|
{ok, Default, Data};
|
||||||
|
[] ->
|
||||||
|
%% No default list, nothing to unblock
|
||||||
|
ok
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
case gen_storage:transaction(LServer, privacy_list_data, F) of
|
||||||
|
{atomic, {error, _} = Error} ->
|
||||||
|
Error;
|
||||||
|
{atomic, ok} ->
|
||||||
|
{result, []};
|
||||||
|
{atomic, {ok, Default, Data}} ->
|
||||||
|
List = list_data_to_items(Data),
|
||||||
|
broadcast_list_update(LUser, LServer, Default, List),
|
||||||
|
broadcast_blocklist_event(LUser, LServer, unblock_all),
|
||||||
|
{result, []};
|
||||||
|
_ ->
|
||||||
|
{error, 'internal-server-error'}
|
||||||
|
end.
|
||||||
|
|
||||||
|
process_blocklist_unblock(LUser, LServer, JIDs) ->
|
||||||
|
F =
|
||||||
|
fun() ->
|
||||||
|
case gen_storage:read(LServer, {privacy_list, {LUser, LServer}}) of
|
||||||
|
[] ->
|
||||||
|
%% No lists, nothing to unblock
|
||||||
|
ok;
|
||||||
|
_ ->
|
||||||
|
case gen_storage:read(LServer, {privacy_default_list, {LUser, LServer}}) of
|
||||||
|
[#privacy_default_list{name = Default}] ->
|
||||||
|
%% Default list, remove matching deny items
|
||||||
|
lists:foreach(
|
||||||
|
fun(JID) ->
|
||||||
|
gen_storage:delete_where(LServer, privacy_list_data,
|
||||||
|
[{'=', user_host, {LUser, LServer}},
|
||||||
|
{'=', name, Default},
|
||||||
|
{'=', action, deny},
|
||||||
|
{'=', match_all, true},
|
||||||
|
{'=', value, JID},
|
||||||
|
{'=', type, jid}])
|
||||||
|
end, JIDs),
|
||||||
|
Data = gen_storage:select(LServer, privacy_list_data,
|
||||||
|
[{'=', user_host, {LUser, LServer}},
|
||||||
|
{'=', name, Default}]),
|
||||||
|
{ok, Default, Data};
|
||||||
|
[] ->
|
||||||
|
%% No default list, nothing to unblock
|
||||||
|
ok
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
case gen_storage:transaction(LServer, privacy_list_data, F) of
|
||||||
|
{atomic, {error, _} = Error} ->
|
||||||
|
Error;
|
||||||
|
{atomic, ok} ->
|
||||||
|
{result, []};
|
||||||
|
{atomic, {ok, Default, Data}} ->
|
||||||
|
List = list_data_to_items(Data),
|
||||||
|
broadcast_list_update(LUser, LServer, Default, List),
|
||||||
|
broadcast_blocklist_event(LUser, LServer, {unblock, JIDs}),
|
||||||
|
{result, []};
|
||||||
|
_ ->
|
||||||
|
{error, 'internal-server-error'}
|
||||||
|
end.
|
||||||
|
|
||||||
|
broadcast_list_update(LUser, LServer, Name, List) ->
|
||||||
|
NeedDb = is_list_needdb(List),
|
||||||
|
JID = exmpp_jid:make(LUser, LServer),
|
||||||
|
ListString = lists:flatten(io_lib:format("~p.", [#userlist{name = Name, list = List, needdb = NeedDb}])),
|
||||||
|
ejabberd_router:route(
|
||||||
|
JID,
|
||||||
|
JID,
|
||||||
|
#xmlel{name = 'broadcast', ns = privacy_list,
|
||||||
|
attrs = [?XMLATTR(<<"list_name">>, Name)],
|
||||||
|
children = [exmpp_xml:cdata(ListString)]}).
|
||||||
|
|
||||||
|
broadcast_blocklist_event(LUser, LServer, Event) ->
|
||||||
|
JID = exmpp_jid:make(LUser, LServer),
|
||||||
|
EventString = lists:flatten(io_lib:format("~p.", [Event])),
|
||||||
|
ejabberd_router:route(
|
||||||
|
JID, JID,
|
||||||
|
#xmlel{name = 'broadcast', ns = blocking,
|
||||||
|
children = [exmpp_xml:cdata(EventString)]}).
|
||||||
|
|
||||||
|
process_blocklist_get(LUser, LServer) ->
|
||||||
|
case catch gen_storage:dirty_read(LServer, privacy_default_list, {LUser, LServer}) of
|
||||||
|
{'EXIT', _Reason} ->
|
||||||
|
{error, 'internal-server-error'};
|
||||||
|
[] ->
|
||||||
|
{result, #xmlel{name = 'blocklist', ns = ?NS_BLOCKING}};
|
||||||
|
[#privacy_default_list{name = Default}] ->
|
||||||
|
JIDs = get_list_blocklist_jids(LUser, LServer, Default),
|
||||||
|
Items = lists:map(
|
||||||
|
fun(JID) ->
|
||||||
|
?DEBUG("JID: ~p",[JID]),
|
||||||
|
#xmlel{name = item, ns = privacy_list,
|
||||||
|
attrs = [?XMLATTR(<<"jid">>, JID)]}
|
||||||
|
end, JIDs),
|
||||||
|
{result,
|
||||||
|
#xmlel{name = 'blocklist', ns = ?NS_BLOCKING, children = Items}}
|
||||||
|
end.
|
|
@ -1,7 +1,7 @@
|
||||||
%%%----------------------------------------------------------------------
|
%%%----------------------------------------------------------------------
|
||||||
%%% File : mod_privacy.erl
|
%%% File : mod_privacy.erl
|
||||||
%%% Author : Alexey Shchepin <alexey@process-one.net>
|
%%% Author : Alexey Shchepin <alexey@process-one.net>
|
||||||
%%% Purpose : jabber:iq:privacy support
|
%%% Purpose : XEP-0016: Privacy Lists
|
||||||
%%% Created : 21 Jul 2003 by Alexey Shchepin <alexey@process-one.net>
|
%%% Created : 21 Jul 2003 by Alexey Shchepin <alexey@process-one.net>
|
||||||
%%%
|
%%%
|
||||||
%%%
|
%%%
|
||||||
|
@ -118,13 +118,6 @@
|
||||||
-include("ejabberd.hrl").
|
-include("ejabberd.hrl").
|
||||||
-include("mod_privacy.hrl").
|
-include("mod_privacy.hrl").
|
||||||
|
|
||||||
-record(privacy_list, {user_host, name}).
|
|
||||||
-record(privacy_default_list, {user_host, name}).
|
|
||||||
-record(privacy_list_data, {user_host, name,
|
|
||||||
type, value, action, order,
|
|
||||||
match_all, match_iq, match_message,
|
|
||||||
match_presence_in, match_presence_out}).
|
|
||||||
|
|
||||||
start(Host, Opts) ->
|
start(Host, Opts) ->
|
||||||
HostB = list_to_binary(Host),
|
HostB = list_to_binary(Host),
|
||||||
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
|
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
|
||||||
|
@ -194,7 +187,7 @@ process_iq(_From, _To, IQ_Rec) ->
|
||||||
exmpp_iq:error(IQ_Rec, 'not-allowed').
|
exmpp_iq:error(IQ_Rec, 'not-allowed').
|
||||||
|
|
||||||
|
|
||||||
process_iq_get(_, From, _To, #iq{payload = SubEl},
|
process_iq_get(_, From, _To, #iq{ns = ?NS_PRIVACY, payload = SubEl},
|
||||||
#userlist{name = Active}) ->
|
#userlist{name = Active}) ->
|
||||||
LUser = exmpp_jid:prep_node(From),
|
LUser = exmpp_jid:prep_node(From),
|
||||||
LServer = exmpp_jid:prep_domain(From),
|
LServer = exmpp_jid:prep_domain(From),
|
||||||
|
@ -211,8 +204,10 @@ process_iq_get(_, From, _To, #iq{payload = SubEl},
|
||||||
end;
|
end;
|
||||||
_ ->
|
_ ->
|
||||||
{error, 'bad-request'}
|
{error, 'bad-request'}
|
||||||
end.
|
end;
|
||||||
|
|
||||||
|
process_iq_get(Acc, _, _, _, _) ->
|
||||||
|
Acc.
|
||||||
|
|
||||||
process_lists_get(LUser, LServer, Active) ->
|
process_lists_get(LUser, LServer, Active) ->
|
||||||
F = fun() ->
|
F = fun() ->
|
||||||
|
@ -352,7 +347,7 @@ list_to_action(S) ->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
process_iq_set(_, From, _To, #iq{payload = SubEl}) ->
|
process_iq_set(_, From, _To, #iq{ns = ?NS_PRIVACY, payload = SubEl}) ->
|
||||||
LUser = exmpp_jid:prep_node(From),
|
LUser = exmpp_jid:prep_node(From),
|
||||||
LServer = exmpp_jid:prep_domain(From),
|
LServer = exmpp_jid:prep_domain(From),
|
||||||
case exmpp_xml:get_child_elements(SubEl) of
|
case exmpp_xml:get_child_elements(SubEl) of
|
||||||
|
@ -371,7 +366,10 @@ process_iq_set(_, From, _To, #iq{payload = SubEl}) ->
|
||||||
end;
|
end;
|
||||||
_ ->
|
_ ->
|
||||||
{error, 'bad-request'}
|
{error, 'bad-request'}
|
||||||
end.
|
end;
|
||||||
|
|
||||||
|
process_iq_set(Acc, _, _, _) ->
|
||||||
|
Acc.
|
||||||
|
|
||||||
|
|
||||||
process_default_set(LUser, LServer, false) ->
|
process_default_set(LUser, LServer, false) ->
|
||||||
|
|
|
@ -19,10 +19,19 @@
|
||||||
%%%
|
%%%
|
||||||
%%%----------------------------------------------------------------------
|
%%%----------------------------------------------------------------------
|
||||||
|
|
||||||
|
-record(privacy_list, {user_host, name}).
|
||||||
|
-record(privacy_default_list, {user_host, name}).
|
||||||
|
-record(privacy_list_data, {user_host, name,
|
||||||
|
type, value, action, order,
|
||||||
|
match_all, match_iq, match_message,
|
||||||
|
match_presence_in, match_presence_out}).
|
||||||
|
|
||||||
|
%% ejabberd 2 format:
|
||||||
-record(privacy, {user_host,
|
-record(privacy, {user_host,
|
||||||
default = none,
|
default = none,
|
||||||
lists = []}).
|
lists = []}).
|
||||||
|
|
||||||
|
%% ejabberd 2 format:
|
||||||
-record(listitem, {type = none,
|
-record(listitem, {type = none,
|
||||||
value = none,
|
value = none,
|
||||||
action,
|
action,
|
||||||
|
@ -35,3 +44,4 @@
|
||||||
}).
|
}).
|
||||||
|
|
||||||
-record(userlist, {name = none, list = [], needdb = false }).
|
-record(userlist, {name = none, list = [], needdb = false }).
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue