mirror of
https://github.com/processone/ejabberd.git
synced 2024-12-26 17:38:45 +01:00
Merge branch 'master' of github.com:processone/ejabberd
This commit is contained in:
commit
afba5bc5f5
@ -890,6 +890,12 @@ The available modules, their purpose and the options allowed by each one are:
|
|||||||
Handles incoming HTTP connections.\\
|
Handles incoming HTTP connections.\\
|
||||||
Options: \texttt{captcha}, \texttt{certfile}, \texttt{default\_host}, \texttt{http\_bind}, \texttt{http\_poll},
|
Options: \texttt{captcha}, \texttt{certfile}, \texttt{default\_host}, \texttt{http\_bind}, \texttt{http\_poll},
|
||||||
\texttt{request\_handlers}, \texttt{tls}, \texttt{tls\_compression}, \texttt{trusted\_proxies}, \texttt{web\_admin}\\
|
\texttt{request\_handlers}, \texttt{tls}, \texttt{tls\_compression}, \texttt{trusted\_proxies}, \texttt{web\_admin}\\
|
||||||
|
\titem{\texttt{ejabberd\_xmlrpc}}
|
||||||
|
Handles XML-RPC requests to execute ejabberd commands (\ref{eja-commands}).\\
|
||||||
|
Options: \texttt{access\_commands}, \texttt{maxsessions}, \texttt{timeout}.\\
|
||||||
|
You can find option explanations, example configuration in old and new format,
|
||||||
|
and example calls in several languages in the old
|
||||||
|
\footahref{https://raw.github.com/processone/ejabberd-contrib/master/ejabberd\_xmlrpc/README.txt}{ejabberd\_xmlrpc README.txt}
|
||||||
\end{description}
|
\end{description}
|
||||||
|
|
||||||
|
|
||||||
@ -4046,15 +4052,28 @@ Options:
|
|||||||
not add/remove/modify contacts,
|
not add/remove/modify contacts,
|
||||||
or subscribe/unsubscribe presence.
|
or subscribe/unsubscribe presence.
|
||||||
By default there aren't restrictions.
|
By default there aren't restrictions.
|
||||||
|
\titem{managers} \ind{options!managers}
|
||||||
|
List of remote entities that can manage users rosters using Remote Roster Management
|
||||||
|
(\xepref{0321}).
|
||||||
|
The protocol sections implemented are:
|
||||||
|
\term{4.2. The remote entity requests current user's roster}.
|
||||||
|
\term{4.3. The user updates roster}.
|
||||||
|
\term{4.4. The remote entity updates the user's roster}.
|
||||||
|
A remote entity cab only get or modify roster items that have the same domain as the entity.
|
||||||
|
Default value is: \term{[]}.
|
||||||
\end{description}
|
\end{description}
|
||||||
|
|
||||||
This example configuration enables Roster Versioning with storage of current id:
|
This example configuration enables Roster Versioning with storage of current id.
|
||||||
|
The ICQ and MSN transports can get ICQ and MSN contacts, add them, or remove them for any local account:
|
||||||
\begin{verbatim}
|
\begin{verbatim}
|
||||||
modules:
|
modules:
|
||||||
...
|
...
|
||||||
mod_roster:
|
mod_roster:
|
||||||
versioning: true
|
versioning: true
|
||||||
store_current_id: true
|
store_current_id: true
|
||||||
|
managers:
|
||||||
|
- "icq.example.org"
|
||||||
|
- "msn.example.org"
|
||||||
...
|
...
|
||||||
\end{verbatim}
|
\end{verbatim}
|
||||||
|
|
||||||
@ -5130,9 +5149,9 @@ with a defined number and type of calling arguments and type of result
|
|||||||
that is registered in the \term{ejabberd\_commands} service.
|
that is registered in the \term{ejabberd\_commands} service.
|
||||||
Those commands can be defined in any Erlang module and executed using any valid frontend.
|
Those commands can be defined in any Erlang module and executed using any valid frontend.
|
||||||
|
|
||||||
\ejabberd{} includes a frontend to execute \term{ejabberd commands}: the script \term{ejabberdctl}.
|
\ejabberd{} includes two frontends to execute \term{ejabberd commands}: the script \term{ejabberdctl} (\ref{ejabberdctl})
|
||||||
|
and the \term{ejabberd\_xmlrpc} listener (\ref{listened-module}).
|
||||||
Other known frontends that can be installed to execute ejabberd commands in different ways are:
|
Other known frontends that can be installed to execute ejabberd commands in different ways are:
|
||||||
\term{ejabberd\_xmlrpc} (XML-RPC service),
|
|
||||||
\term{mod\_rest} (HTTP POST service),
|
\term{mod\_rest} (HTTP POST service),
|
||||||
\term{mod\_shcommands} (ejabberd WebAdmin page).
|
\term{mod\_shcommands} (ejabberd WebAdmin page).
|
||||||
|
|
||||||
|
@ -599,12 +599,11 @@ modules:
|
|||||||
##
|
##
|
||||||
## Enable modules with custom options in a specific virtual host
|
## Enable modules with custom options in a specific virtual host
|
||||||
##
|
##
|
||||||
## host_config:
|
## append_host_config:
|
||||||
## "localhost":
|
## "localhost":
|
||||||
## add:
|
## modules:
|
||||||
## modules:
|
## mod_echo:
|
||||||
## mod_echo:
|
## host: "mirror.localhost"
|
||||||
## host: "mirror.localhost"
|
|
||||||
|
|
||||||
### Local Variables:
|
### Local Variables:
|
||||||
### mode: yaml
|
### mode: yaml
|
||||||
|
@ -16,7 +16,7 @@ Cfg = case file:consult("vars.config") of
|
|||||||
Macros = lists:flatmap(
|
Macros = lists:flatmap(
|
||||||
fun({roster_gateway_workaround, true}) ->
|
fun({roster_gateway_workaround, true}) ->
|
||||||
[{d, 'ROSTER_GATEWAY_WORKAROUND'}];
|
[{d, 'ROSTER_GATEWAY_WORKAROUND'}];
|
||||||
({transient_supervisors, true}) ->
|
({transient_supervisors, false}) ->
|
||||||
[{d, 'NO_TRANSIENT_SUPERVISORS'}];
|
[{d, 'NO_TRANSIENT_SUPERVISORS'}];
|
||||||
({nif, true}) ->
|
({nif, true}) ->
|
||||||
[{d, 'NIF'}];
|
[{d, 'NIF'}];
|
||||||
|
@ -94,7 +94,7 @@
|
|||||||
tls_options = [],
|
tls_options = [],
|
||||||
authenticated = false,
|
authenticated = false,
|
||||||
jid,
|
jid,
|
||||||
user = "", server = ?MYNAME, resource = <<"">>,
|
user = "", server = <<"">>, resource = <<"">>,
|
||||||
sid,
|
sid,
|
||||||
pres_t = ?SETS:new(),
|
pres_t = ?SETS:new(),
|
||||||
pres_f = ?SETS:new(),
|
pres_f = ?SETS:new(),
|
||||||
@ -291,7 +291,12 @@ wait_for_stream({xmlstreamstart, _Name, Attrs}, StateData) ->
|
|||||||
DefaultLang = ?MYLANG,
|
DefaultLang = ?MYLANG,
|
||||||
case xml:get_attr_s(<<"xmlns:stream">>, Attrs) of
|
case xml:get_attr_s(<<"xmlns:stream">>, Attrs) of
|
||||||
?NS_STREAM ->
|
?NS_STREAM ->
|
||||||
Server = jlib:nameprep(xml:get_attr_s(<<"to">>, Attrs)),
|
Server =
|
||||||
|
case StateData#state.server of
|
||||||
|
<<"">> ->
|
||||||
|
jlib:nameprep(xml:get_attr_s(<<"to">>, Attrs));
|
||||||
|
S -> S
|
||||||
|
end,
|
||||||
case lists:member(Server, ?MYHOSTS) of
|
case lists:member(Server, ?MYHOSTS) of
|
||||||
true ->
|
true ->
|
||||||
Lang = case xml:get_attr_s(<<"xml:lang">>, Attrs) of
|
Lang = case xml:get_attr_s(<<"xml:lang">>, Attrs) of
|
||||||
@ -647,6 +652,7 @@ wait_for_feature_request({xmlstreamelement, El},
|
|||||||
StateData#state{streamid = new_id(),
|
StateData#state{streamid = new_id(),
|
||||||
authenticated = true,
|
authenticated = true,
|
||||||
auth_module = AuthModule,
|
auth_module = AuthModule,
|
||||||
|
sasl_state = undefined,
|
||||||
user = U});
|
user = U});
|
||||||
{continue, ServerOut, NewSASLState} ->
|
{continue, ServerOut, NewSASLState} ->
|
||||||
send_element(StateData,
|
send_element(StateData,
|
||||||
@ -804,6 +810,7 @@ wait_for_sasl_response({xmlstreamelement, El},
|
|||||||
StateData#state{streamid = new_id(),
|
StateData#state{streamid = new_id(),
|
||||||
authenticated = true,
|
authenticated = true,
|
||||||
auth_module = AuthModule,
|
auth_module = AuthModule,
|
||||||
|
sasl_state = undefined,
|
||||||
user = U});
|
user = U});
|
||||||
{ok, Props, ServerOut} ->
|
{ok, Props, ServerOut} ->
|
||||||
(StateData#state.sockmod):reset_stream(StateData#state.socket),
|
(StateData#state.sockmod):reset_stream(StateData#state.socket),
|
||||||
@ -824,6 +831,7 @@ wait_for_sasl_response({xmlstreamelement, El},
|
|||||||
StateData#state{streamid = new_id(),
|
StateData#state{streamid = new_id(),
|
||||||
authenticated = true,
|
authenticated = true,
|
||||||
auth_module = AuthModule,
|
auth_module = AuthModule,
|
||||||
|
sasl_state = undefined,
|
||||||
user = U});
|
user = U});
|
||||||
{continue, ServerOut, NewSASLState} ->
|
{continue, ServerOut, NewSASLState} ->
|
||||||
send_element(StateData,
|
send_element(StateData,
|
||||||
|
@ -484,7 +484,7 @@ abort_on_driver_error(Reply, From) ->
|
|||||||
%% Open an ODBC database connection
|
%% Open an ODBC database connection
|
||||||
odbc_connect(SQLServer) ->
|
odbc_connect(SQLServer) ->
|
||||||
ejabberd:start_app(odbc),
|
ejabberd:start_app(odbc),
|
||||||
odbc:connect(SQLServer, [{scrollable_cursors, off}]).
|
odbc:connect(binary_to_list(SQLServer), [{scrollable_cursors, off}]).
|
||||||
|
|
||||||
%% == Native PostgreSQL code
|
%% == Native PostgreSQL code
|
||||||
|
|
||||||
|
@ -88,7 +88,7 @@
|
|||||||
|
|
||||||
-define(SUPERVISOR_START,
|
-define(SUPERVISOR_START,
|
||||||
p1_fsm:start(ejabberd_s2s_in, [SockData, Opts],
|
p1_fsm:start(ejabberd_s2s_in, [SockData, Opts],
|
||||||
?FSMOPTS ++ fsm_limit_opts(Opts)).
|
?FSMOPTS ++ fsm_limit_opts(Opts))).
|
||||||
|
|
||||||
-else.
|
-else.
|
||||||
|
|
||||||
|
@ -1570,9 +1570,7 @@ user_info(User, Server, Query, Lang) ->
|
|||||||
end,
|
end,
|
||||||
lists:sort(Resources))))]
|
lists:sort(Resources))))]
|
||||||
end,
|
end,
|
||||||
Password = ejabberd_auth:get_password_s(User, Server),
|
FPassword = [?INPUT(<<"text">>, <<"password">>, <<"">>),
|
||||||
FPassword = [?INPUT(<<"password">>, <<"password">>,
|
|
||||||
Password),
|
|
||||||
?C(<<" ">>),
|
?C(<<" ">>),
|
||||||
?INPUTT(<<"submit">>, <<"chpassword">>,
|
?INPUTT(<<"submit">>, <<"chpassword">>,
|
||||||
<<"Change Password">>)],
|
<<"Change Password">>)],
|
||||||
|
@ -345,8 +345,10 @@ build_fault_response(Code, ParseString, ParseArgs) ->
|
|||||||
do_command(AccessCommands, Auth, Command, AttrL, ArgsF,
|
do_command(AccessCommands, Auth, Command, AttrL, ArgsF,
|
||||||
ResultF) ->
|
ResultF) ->
|
||||||
ArgsFormatted = format_args(AttrL, ArgsF),
|
ArgsFormatted = format_args(AttrL, ArgsF),
|
||||||
|
{UserT, ServerT, PasswordT} = Auth,
|
||||||
|
AuthBin = {list_to_binary(UserT), list_to_binary(ServerT), list_to_binary(PasswordT)},
|
||||||
Result =
|
Result =
|
||||||
ejabberd_commands:execute_command(AccessCommands, Auth,
|
ejabberd_commands:execute_command(AccessCommands, AuthBin,
|
||||||
Command, ArgsFormatted),
|
Command, ArgsFormatted),
|
||||||
ResultFormatted = format_result(Result, ResultF),
|
ResultFormatted = format_result(Result, ResultF),
|
||||||
{command_result, ResultFormatted}.
|
{command_result, ResultFormatted}.
|
||||||
|
@ -149,7 +149,7 @@ check_and_forward(JID, #xmlel{name = <<"message">>, attrs = Attrs} = Packet, Dir
|
|||||||
<<"chat">> ->
|
<<"chat">> ->
|
||||||
case xml:get_subtag(Packet, <<"private">>) of
|
case xml:get_subtag(Packet, <<"private">>) of
|
||||||
false ->
|
false ->
|
||||||
case xml:get_subtag(Packet,<<"forwarded">>) of
|
case xml:get_subtag(Packet,<<"received">>) of
|
||||||
false ->
|
false ->
|
||||||
send_copies(JID, Packet, Direction);
|
send_copies(JID, Packet, Direction);
|
||||||
_ ->
|
_ ->
|
||||||
|
@ -657,7 +657,7 @@ load_permanent_rooms(Host, ServerHost, Access, HistorySize, RoomShaper) ->
|
|||||||
start_new_room(Host, ServerHost, Access, Room,
|
start_new_room(Host, ServerHost, Access, Room,
|
||||||
HistorySize, RoomShaper, From,
|
HistorySize, RoomShaper, From,
|
||||||
Nick, DefRoomOpts) ->
|
Nick, DefRoomOpts) ->
|
||||||
case restore_room(ServerHost, Room, Host) of
|
case restore_room(ServerHost, Host, Room) of
|
||||||
error ->
|
error ->
|
||||||
?DEBUG("MUC: open new room '~s'~n", [Room]),
|
?DEBUG("MUC: open new room '~s'~n", [Room]),
|
||||||
mod_muc_room:start(Host, ServerHost, Access,
|
mod_muc_room:start(Host, ServerHost, Access,
|
||||||
|
@ -2334,6 +2334,14 @@ send_nick_changing(JID, OldNick, StateData,
|
|||||||
[{<<"affiliation">>, SAffiliation},
|
[{<<"affiliation">>, SAffiliation},
|
||||||
{<<"role">>, SRole}]
|
{<<"role">>, SRole}]
|
||||||
end,
|
end,
|
||||||
|
Status110 = case JID == Info#user.jid of
|
||||||
|
true ->
|
||||||
|
[#xmlel{name = <<"status">>,
|
||||||
|
attrs = [{<<"code">>, <<"110">>}]
|
||||||
|
}];
|
||||||
|
false ->
|
||||||
|
[]
|
||||||
|
end,
|
||||||
Packet1 = #xmlel{name = <<"presence">>,
|
Packet1 = #xmlel{name = <<"presence">>,
|
||||||
attrs =
|
attrs =
|
||||||
[{<<"type">>,
|
[{<<"type">>,
|
||||||
@ -2356,7 +2364,7 @@ send_nick_changing(JID, OldNick, StateData,
|
|||||||
[{<<"code">>,
|
[{<<"code">>,
|
||||||
<<"303">>}],
|
<<"303">>}],
|
||||||
children =
|
children =
|
||||||
[]}]}]},
|
[]}|Status110]}]},
|
||||||
Packet2 = xml:append_subtags(Presence,
|
Packet2 = xml:append_subtags(Presence,
|
||||||
[#xmlel{name = <<"x">>,
|
[#xmlel{name = <<"x">>,
|
||||||
attrs =
|
attrs =
|
||||||
@ -2371,7 +2379,7 @@ send_nick_changing(JID, OldNick, StateData,
|
|||||||
ItemAttrs2,
|
ItemAttrs2,
|
||||||
children
|
children
|
||||||
=
|
=
|
||||||
[]}]}]),
|
[]}|Status110]}]),
|
||||||
if SendOldUnavailable ->
|
if SendOldUnavailable ->
|
||||||
ejabberd_router:route(jlib:jid_replace_resource(StateData#state.jid,
|
ejabberd_router:route(jlib:jid_replace_resource(StateData#state.jid,
|
||||||
OldNick),
|
OldNick),
|
||||||
|
@ -130,6 +130,9 @@ stop(Host) ->
|
|||||||
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host,
|
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host,
|
||||||
?NS_ROSTER).
|
?NS_ROSTER).
|
||||||
|
|
||||||
|
process_iq(From, To, IQ) when ((From#jid.luser == <<"">>) andalso (From#jid.resource == <<"">>)) ->
|
||||||
|
process_iq_manager(From, To, IQ);
|
||||||
|
|
||||||
process_iq(From, To, IQ) ->
|
process_iq(From, To, IQ) ->
|
||||||
#iq{sub_el = SubEl} = IQ,
|
#iq{sub_el = SubEl} = IQ,
|
||||||
#jid{lserver = LServer} = From,
|
#jid{lserver = LServer} = From,
|
||||||
@ -465,15 +468,16 @@ try_process_iq_set(From, To, #iq{sub_el = SubEl} = IQ) ->
|
|||||||
process_iq_set(From, To, IQ)
|
process_iq_set(From, To, IQ)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
process_iq_set(From, To, #iq{sub_el = SubEl} = IQ) ->
|
process_iq_set(From, To, #iq{sub_el = SubEl, id = Id} = IQ) ->
|
||||||
#xmlel{children = Els} = SubEl,
|
#xmlel{children = Els} = SubEl,
|
||||||
lists:foreach(fun (El) -> process_item_set(From, To, El)
|
Managed = is_managed_from_id(Id),
|
||||||
|
lists:foreach(fun (El) -> process_item_set(From, To, El, Managed)
|
||||||
end,
|
end,
|
||||||
Els),
|
Els),
|
||||||
IQ#iq{type = result, sub_el = []}.
|
IQ#iq{type = result, sub_el = []}.
|
||||||
|
|
||||||
process_item_set(From, To,
|
process_item_set(From, To,
|
||||||
#xmlel{attrs = Attrs, children = Els}) ->
|
#xmlel{attrs = Attrs, children = Els}, Managed) ->
|
||||||
JID1 = jlib:string_to_jid(xml:get_attr_s(<<"jid">>,
|
JID1 = jlib:string_to_jid(xml:get_attr_s(<<"jid">>,
|
||||||
Attrs)),
|
Attrs)),
|
||||||
#jid{user = User, luser = LUser, lserver = LServer} =
|
#jid{user = User, luser = LUser, lserver = LServer} =
|
||||||
@ -484,12 +488,13 @@ process_item_set(From, To,
|
|||||||
LJID = jlib:jid_tolower(JID1),
|
LJID = jlib:jid_tolower(JID1),
|
||||||
F = fun () ->
|
F = fun () ->
|
||||||
Item = get_roster_by_jid_t(LUser, LServer, LJID),
|
Item = get_roster_by_jid_t(LUser, LServer, LJID),
|
||||||
Item1 = process_item_attrs(Item, Attrs),
|
Item1 = process_item_attrs_managed(Item, Attrs, Managed),
|
||||||
Item2 = process_item_els(Item1, Els),
|
Item2 = process_item_els(Item1, Els),
|
||||||
case Item2#roster.subscription of
|
case Item2#roster.subscription of
|
||||||
remove -> del_roster_t(LUser, LServer, LJID);
|
remove -> del_roster_t(LUser, LServer, LJID);
|
||||||
_ -> update_roster_t(LUser, LServer, LJID, Item2)
|
_ -> update_roster_t(LUser, LServer, LJID, Item2)
|
||||||
end,
|
end,
|
||||||
|
send_itemset_to_managers(From, Item2, Managed),
|
||||||
Item3 = ejabberd_hooks:run_fold(roster_process_item,
|
Item3 = ejabberd_hooks:run_fold(roster_process_item,
|
||||||
LServer, Item2,
|
LServer, Item2,
|
||||||
[LServer]),
|
[LServer]),
|
||||||
@ -511,7 +516,7 @@ process_item_set(From, To,
|
|||||||
?DEBUG("ROSTER: roster item set error: ~p~n", [E]), ok
|
?DEBUG("ROSTER: roster item set error: ~p~n", [E]), ok
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
process_item_set(_From, _To, _) -> ok.
|
process_item_set(_From, _To, _, _Managed) -> ok.
|
||||||
|
|
||||||
process_item_attrs(Item, [{Attr, Val} | Attrs]) ->
|
process_item_attrs(Item, [{Attr, Val} | Attrs]) ->
|
||||||
case Attr of
|
case Attr of
|
||||||
@ -1554,6 +1559,91 @@ webadmin_user(Acc, _User, _Server, Lang) ->
|
|||||||
Acc ++
|
Acc ++
|
||||||
[?XE(<<"h3">>, [?ACT(<<"roster/">>, <<"Roster">>)])].
|
[?XE(<<"h3">>, [?ACT(<<"roster/">>, <<"Roster">>)])].
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
%% Implement XEP-0321 Remote Roster Management
|
||||||
|
|
||||||
|
process_iq_manager(From, To, IQ) ->
|
||||||
|
%% Check what access is allowed for From to To
|
||||||
|
MatchDomain = From#jid.lserver,
|
||||||
|
case is_domain_managed(MatchDomain, To#jid.lserver) of
|
||||||
|
true ->
|
||||||
|
process_iq_manager2(MatchDomain, To, IQ);
|
||||||
|
false ->
|
||||||
|
#iq{sub_el = SubEl} = IQ,
|
||||||
|
IQ#iq{type = error, sub_el = [SubEl, ?ERR_BAD_REQUEST]}
|
||||||
|
end.
|
||||||
|
|
||||||
|
process_iq_manager2(MatchDomain, To, IQ) ->
|
||||||
|
%% If IQ is SET, filter the input IQ
|
||||||
|
IQFiltered = maybe_filter_request(MatchDomain, IQ),
|
||||||
|
%% Call the standard function with reversed JIDs
|
||||||
|
IdInitial = IQFiltered#iq.id,
|
||||||
|
ResIQ = process_iq(To, To, IQFiltered#iq{id = <<"roster-remotely-managed">>}),
|
||||||
|
%% Filter the output IQ
|
||||||
|
filter_stanza(MatchDomain, ResIQ#iq{id = IdInitial}).
|
||||||
|
|
||||||
|
is_domain_managed(ContactHost, UserHost) ->
|
||||||
|
Managers = gen_mod:get_module_opt(UserHost, ?MODULE, managers,
|
||||||
|
fun(B) when is_list(B) -> B end,
|
||||||
|
[]),
|
||||||
|
lists:member(ContactHost, Managers).
|
||||||
|
|
||||||
|
maybe_filter_request(MatchDomain, IQ) when IQ#iq.type == set ->
|
||||||
|
filter_stanza(MatchDomain, IQ);
|
||||||
|
maybe_filter_request(_MatchDomain, IQ) ->
|
||||||
|
IQ.
|
||||||
|
|
||||||
|
filter_stanza(_MatchDomain, #iq{sub_el = []} = IQ) ->
|
||||||
|
IQ;
|
||||||
|
filter_stanza(MatchDomain, #iq{sub_el = [SubEl | _]} = IQ) ->
|
||||||
|
#iq{sub_el = SubElFiltered} = IQRes =
|
||||||
|
filter_stanza(MatchDomain, IQ#iq{sub_el = SubEl}),
|
||||||
|
IQRes#iq{sub_el = [SubElFiltered]};
|
||||||
|
filter_stanza(MatchDomain, #iq{sub_el = SubEl} = IQ) ->
|
||||||
|
#xmlel{name = Type, attrs = Attrs, children = Items} = SubEl,
|
||||||
|
ItemsFiltered = lists:filter(
|
||||||
|
fun(Item) ->
|
||||||
|
is_item_of_domain(MatchDomain, Item) end, Items),
|
||||||
|
SubElFiltered = #xmlel{name=Type, attrs = Attrs, children = ItemsFiltered},
|
||||||
|
IQ#iq{sub_el = SubElFiltered}.
|
||||||
|
|
||||||
|
is_item_of_domain(MatchDomain, #xmlel{} = El) ->
|
||||||
|
lists:any(fun(Attr) -> is_jid_of_domain(MatchDomain, Attr) end, El#xmlel.attrs);
|
||||||
|
is_item_of_domain(_MatchDomain, {xmlcdata, _}) ->
|
||||||
|
false.
|
||||||
|
|
||||||
|
is_jid_of_domain(MatchDomain, {<<"jid">>, JIDString}) ->
|
||||||
|
case jlib:string_to_jid(JIDString) of
|
||||||
|
JID when JID#jid.lserver == MatchDomain -> true;
|
||||||
|
_ -> false
|
||||||
|
end;
|
||||||
|
is_jid_of_domain(_, _) ->
|
||||||
|
false.
|
||||||
|
|
||||||
|
process_item_attrs_managed(Item, Attrs, true) ->
|
||||||
|
process_item_attrs_ws(Item, Attrs);
|
||||||
|
process_item_attrs_managed(Item, _Attrs, false) ->
|
||||||
|
process_item_attrs(Item, _Attrs).
|
||||||
|
|
||||||
|
send_itemset_to_managers(_From, _Item, true) ->
|
||||||
|
ok;
|
||||||
|
send_itemset_to_managers(From, Item, false) ->
|
||||||
|
{_, UserHost} = Item#roster.us,
|
||||||
|
{_ContactUser, ContactHost, _ContactResource} = Item#roster.jid,
|
||||||
|
%% Check if the component is an allowed manager
|
||||||
|
IsManager = is_domain_managed(ContactHost, UserHost),
|
||||||
|
case IsManager of
|
||||||
|
true -> push_item(<<"">>, ContactHost, <<"">>, From, Item);
|
||||||
|
false -> ok
|
||||||
|
end.
|
||||||
|
|
||||||
|
is_managed_from_id(<<"roster-remotely-managed">>) ->
|
||||||
|
true;
|
||||||
|
is_managed_from_id(_Id) ->
|
||||||
|
false.
|
||||||
|
|
||||||
|
|
||||||
export(_Server) ->
|
export(_Server) ->
|
||||||
[{roster,
|
[{roster,
|
||||||
fun(Host, #roster{usj = {LUser, LServer, LJID}} = R)
|
fun(Host, #roster{usj = {LUser, LServer, LJID}} = R)
|
||||||
|
Loading…
Reference in New Issue
Block a user