diff options
Diffstat (limited to 'src/mod_adhoc.erl')
-rw-r--r-- | src/mod_adhoc.erl | 205 |
1 files changed, 96 insertions, 109 deletions
diff --git a/src/mod_adhoc.erl b/src/mod_adhoc.erl index e12e0de1e..edba1cebe 100644 --- a/src/mod_adhoc.erl +++ b/src/mod_adhoc.erl @@ -5,7 +5,7 @@ %%% Created : 15 Nov 2005 by Magnus Henoch <henoch@dtek.chalmers.se> %%% %%% -%%% ejabberd, Copyright (C) 2002-2016 ProcessOne +%%% ejabberd, Copyright (C) 2002-2019 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as @@ -31,27 +31,22 @@ -behaviour(gen_mod). --export([start/2, stop/1, process_local_iq/3, - process_sm_iq/3, get_local_commands/5, +-export([start/2, stop/1, reload/3, process_local_iq/1, + process_sm_iq/1, get_local_commands/5, get_local_identity/5, get_local_features/5, get_sm_commands/5, get_sm_identity/5, get_sm_features/5, - ping_item/4, ping_command/4, mod_opt_type/1, depends/2]). + ping_item/4, ping_command/4, mod_opt_type/1, depends/2, + mod_options/1]). --include("ejabberd.hrl"). -include("logger.hrl"). +-include("xmpp.hrl"). +-include("translate.hrl"). --include("jlib.hrl"). - --include("adhoc.hrl"). - -start(Host, Opts) -> - IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1, - one_queue), +start(Host, _Opts) -> gen_iq_handler:add_iq_handler(ejabberd_local, Host, - ?NS_COMMANDS, ?MODULE, process_local_iq, - IQDisc), + ?NS_COMMANDS, ?MODULE, process_local_iq), gen_iq_handler:add_iq_handler(ejabberd_sm, Host, - ?NS_COMMANDS, ?MODULE, process_sm_iq, IQDisc), + ?NS_COMMANDS, ?MODULE, process_sm_iq), ejabberd_hooks:add(disco_local_identity, Host, ?MODULE, get_local_identity, 99), ejabberd_hooks:add(disco_local_features, Host, ?MODULE, @@ -91,15 +86,15 @@ stop(Host) -> gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_COMMANDS). -%------------------------------------------------------------------------- +reload(_Host, _NewOpts, _OldOpts) -> + ok. +%------------------------------------------------------------------------- +-spec get_local_commands(mod_disco:items_acc(), jid(), jid(), binary(), binary()) -> mod_disco:items_acc(). get_local_commands(Acc, _From, #jid{server = Server, lserver = LServer} = _To, <<"">>, Lang) -> - Display = gen_mod:get_module_opt(LServer, ?MODULE, - report_commands_node, - fun(B) when is_boolean(B) -> B end, - false), + Display = mod_adhoc_opt:report_commands_node(LServer), case Display of false -> Acc; _ -> @@ -107,12 +102,9 @@ get_local_commands(Acc, _From, {result, I} -> I; _ -> [] end, - Nodes = [#xmlel{name = <<"item">>, - attrs = - [{<<"jid">>, Server}, {<<"node">>, ?NS_COMMANDS}, - {<<"name">>, - translate:translate(Lang, <<"Commands">>)}], - children = []}], + Nodes = [#disco_item{jid = jid:make(Server), + node = ?NS_COMMANDS, + name = translate:translate(Lang, ?T("Commands"))}], {result, Items ++ Nodes} end; get_local_commands(_Acc, From, @@ -126,13 +118,10 @@ get_local_commands(Acc, _From, _To, _Node, _Lang) -> Acc. %------------------------------------------------------------------------- - +-spec get_sm_commands(mod_disco:items_acc(), jid(), jid(), binary(), binary()) -> mod_disco:items_acc(). get_sm_commands(Acc, _From, #jid{lserver = LServer} = To, <<"">>, Lang) -> - Display = gen_mod:get_module_opt(LServer, ?MODULE, - report_commands_node, - fun(B) when is_boolean(B) -> B end, - false), + Display = mod_adhoc_opt:report_commands_node(LServer), case Display of false -> Acc; _ -> @@ -140,13 +129,9 @@ get_sm_commands(Acc, _From, {result, I} -> I; _ -> [] end, - Nodes = [#xmlel{name = <<"item">>, - attrs = - [{<<"jid">>, jid:to_string(To)}, - {<<"node">>, ?NS_COMMANDS}, - {<<"name">>, - translate:translate(Lang, <<"Commands">>)}], - children = []}], + Nodes = [#disco_item{jid = To, + node = ?NS_COMMANDS, + name = translate:translate(Lang, ?T("Commands"))}], {result, Items ++ Nodes} end; get_sm_commands(_Acc, From, @@ -156,45 +141,34 @@ get_sm_commands(_Acc, From, get_sm_commands(Acc, _From, _To, _Node, _Lang) -> Acc. %------------------------------------------------------------------------- - +-spec get_local_identity([identity()], jid(), jid(), binary(), binary()) -> [identity()]. %% On disco info request to the ad-hoc node, return automation/command-list. get_local_identity(Acc, _From, _To, ?NS_COMMANDS, Lang) -> - [#xmlel{name = <<"identity">>, - attrs = - [{<<"category">>, <<"automation">>}, - {<<"type">>, <<"command-list">>}, - {<<"name">>, - translate:translate(Lang, <<"Commands">>)}], - children = []} + [#identity{category = <<"automation">>, + type = <<"command-list">>, + name = translate:translate(Lang, ?T("Commands"))} | Acc]; get_local_identity(Acc, _From, _To, <<"ping">>, Lang) -> - [#xmlel{name = <<"identity">>, - attrs = - [{<<"category">>, <<"automation">>}, - {<<"type">>, <<"command-node">>}, - {<<"name">>, translate:translate(Lang, <<"Ping">>)}], - children = []} + [#identity{category = <<"automation">>, + type = <<"command-node">>, + name = translate:translate(Lang, ?T("Ping"))} | Acc]; get_local_identity(Acc, _From, _To, _Node, _Lang) -> Acc. %------------------------------------------------------------------------- - +-spec get_sm_identity([identity()], jid(), jid(), binary(), binary()) -> [identity()]. %% On disco info request to the ad-hoc node, return automation/command-list. get_sm_identity(Acc, _From, _To, ?NS_COMMANDS, Lang) -> - [#xmlel{name = <<"identity">>, - attrs = - [{<<"category">>, <<"automation">>}, - {<<"type">>, <<"command-list">>}, - {<<"name">>, - translate:translate(Lang, <<"Commands">>)}], - children = []} + [#identity{category = <<"automation">>, + type = <<"command-list">>, + name = translate:translate(Lang, ?T("Commands"))} | Acc]; get_sm_identity(Acc, _From, _To, _Node, _Lang) -> Acc. %------------------------------------------------------------------------- - +-spec get_local_features(mod_disco:features_acc(), jid(), jid(), binary(), binary()) -> mod_disco:features_acc(). get_local_features(Acc, _From, _To, <<"">>, _Lang) -> Feats = case Acc of {result, I} -> I; @@ -211,7 +185,7 @@ get_local_features(Acc, _From, _To, _Node, _Lang) -> Acc. %------------------------------------------------------------------------- - +-spec get_sm_features(mod_disco:features_acc(), jid(), jid(), binary(), binary()) -> mod_disco:features_acc(). get_sm_features(Acc, _From, _To, <<"">>, _Lang) -> Feats = case Acc of {result, I} -> I; @@ -224,70 +198,83 @@ get_sm_features(_Acc, _From, _To, ?NS_COMMANDS, get_sm_features(Acc, _From, _To, _Node, _Lang) -> Acc. %------------------------------------------------------------------------- +-spec process_local_iq(iq()) -> iq() | ignore. +process_local_iq(IQ) -> + process_adhoc_request(IQ, local). -process_local_iq(From, To, IQ) -> - process_adhoc_request(From, To, IQ, - adhoc_local_commands). - -process_sm_iq(From, To, IQ) -> - process_adhoc_request(From, To, IQ, adhoc_sm_commands). +-spec process_sm_iq(iq()) -> iq() | ignore. +process_sm_iq(IQ) -> + process_adhoc_request(IQ, sm). -process_adhoc_request(From, To, - #iq{sub_el = SubEl, lang = Lang} = IQ, Hook) -> - ?DEBUG("About to parse ~p...", [IQ]), - case adhoc:parse_request(IQ) of - {error, Error} -> - IQ#iq{type = error, sub_el = [SubEl, Error]}; - #adhoc_request{} = AdhocRequest -> - Host = To#jid.lserver, - case ejabberd_hooks:run_fold(Hook, Host, empty, - [From, To, AdhocRequest]) - of - ignore -> ignore; - empty -> - Txt = <<"No hook has processed this command">>, - IQ#iq{type = error, - sub_el = [SubEl, ?ERRT_ITEM_NOT_FOUND(Lang, Txt)]}; - {error, Error} -> - IQ#iq{type = error, sub_el = [SubEl, Error]}; - Command -> IQ#iq{type = result, sub_el = [Command]} - end - end. +-spec process_adhoc_request(iq(), sm | local) -> iq() | ignore. +process_adhoc_request(#iq{from = From, to = To, + type = set, lang = Lang, + sub_els = [#adhoc_command{} = SubEl]} = IQ, Type) -> + Host = To#jid.lserver, + Res = case Type of + local -> + ejabberd_hooks:run_fold(adhoc_local_commands, Host, empty, + [From, To, fix_lang(Lang, SubEl)]); + sm -> + ejabberd_hooks:run_fold(adhoc_sm_commands, Host, empty, + [From, To, fix_lang(Lang, SubEl)]) + end, + case Res of + ignore -> + ignore; + empty -> + Txt = ?T("No hook has processed this command"), + xmpp:make_error(IQ, xmpp:err_item_not_found(Txt, Lang)); + {error, Error} -> + xmpp:make_error(IQ, Error); + Command -> + xmpp:make_iq_result(IQ, Command) + end; +process_adhoc_request(#iq{} = IQ, _Hooks) -> + xmpp:make_error(IQ, xmpp:err_bad_request()). +-spec ping_item(mod_disco:items_acc(), jid(), jid(), binary()) -> {result, [disco_item()]}. ping_item(Acc, _From, #jid{server = Server} = _To, Lang) -> Items = case Acc of {result, I} -> I; _ -> [] end, - Nodes = [#xmlel{name = <<"item">>, - attrs = - [{<<"jid">>, Server}, {<<"node">>, <<"ping">>}, - {<<"name">>, translate:translate(Lang, <<"Ping">>)}], - children = []}], + Nodes = [#disco_item{jid = jid:make(Server), + node = <<"ping">>, + name = translate:translate(Lang, ?T("Ping"))}], {result, Items ++ Nodes}. +-spec ping_command(adhoc_command(), jid(), jid(), adhoc_command()) -> + adhoc_command() | {error, stanza_error()}. ping_command(_Acc, _From, _To, - #adhoc_request{lang = Lang, node = <<"ping">>, - sessionid = _Sessionid, action = Action} = - Request) -> - if Action == <<"">>; Action == <<"execute">> -> - adhoc:produce_response(Request, - #adhoc_response{status = completed, - notes = - [{<<"info">>, - translate:translate(Lang, - <<"Pong">>)}]}); + #adhoc_command{lang = Lang, node = <<"ping">>, + action = Action} = Request) -> + if Action == execute -> + xmpp_util:make_adhoc_response( + Request, + #adhoc_command{ + status = completed, + notes = [#adhoc_note{ + type = info, + data = translate:translate(Lang, ?T("Pong"))}]}); true -> - Txt = <<"Incorrect value of 'action' attribute">>, - {error, ?ERRT_BAD_REQUEST(Lang, Txt)} + Txt = ?T("Incorrect value of 'action' attribute"), + {error, xmpp:err_bad_request(Txt, Lang)} end; ping_command(Acc, _From, _To, _Request) -> Acc. +-spec fix_lang(binary(), adhoc_command()) -> adhoc_command(). +fix_lang(Lang, #adhoc_command{lang = <<>>} = Cmd) -> + Cmd#adhoc_command{lang = Lang}; +fix_lang(_, Cmd) -> + Cmd. + depends(_Host, _Opts) -> []. -mod_opt_type(iqdisc) -> fun gen_iq_handler:check_type/1; mod_opt_type(report_commands_node) -> - fun (B) when is_boolean(B) -> B end; -mod_opt_type(_) -> [iqdisc, report_commands_node]. + econf:bool(). + +mod_options(_Host) -> + [{report_commands_node, false}]. |