mirror of
https://github.com/processone/ejabberd.git
synced 2024-11-24 16:23:40 +01:00
Rewrite mod_adhoc and mod_announce to use XML generator
This commit is contained in:
parent
179fcd9521
commit
da310a5173
@ -18,6 +18,10 @@
|
|||||||
-record(feature_register, {}).
|
-record(feature_register, {}).
|
||||||
-type feature_register() :: #feature_register{}.
|
-type feature_register() :: #feature_register{}.
|
||||||
|
|
||||||
|
-record(adhoc_note, {type = info :: 'error' | 'info' | 'warn',
|
||||||
|
data = <<>> :: binary()}).
|
||||||
|
-type adhoc_note() :: #adhoc_note{}.
|
||||||
|
|
||||||
-record(address, {type :: 'bcc' | 'cc' | 'noreply' | 'ofrom' | 'replyroom' | 'replyto' | 'to',
|
-record(address, {type :: 'bcc' | 'cc' | 'noreply' | 'ofrom' | 'replyroom' | 'replyto' | 'to',
|
||||||
jid :: any(),
|
jid :: any(),
|
||||||
desc :: binary(),
|
desc :: binary(),
|
||||||
@ -419,6 +423,12 @@
|
|||||||
sid :: binary()}).
|
sid :: binary()}).
|
||||||
-type bytestreams() :: #bytestreams{}.
|
-type bytestreams() :: #bytestreams{}.
|
||||||
|
|
||||||
|
-record(adhoc_actions, {execute :: 'complete' | 'next' | 'prev',
|
||||||
|
prev = false :: boolean(),
|
||||||
|
next = false :: boolean(),
|
||||||
|
complete = false :: boolean()}).
|
||||||
|
-type adhoc_actions() :: #adhoc_actions{}.
|
||||||
|
|
||||||
-record(vcard_org, {name :: binary(),
|
-record(vcard_org, {name :: binary(),
|
||||||
units = [] :: [binary()]}).
|
units = [] :: [binary()]}).
|
||||||
-type vcard_org() :: #vcard_org{}.
|
-type vcard_org() :: #vcard_org{}.
|
||||||
@ -559,6 +569,16 @@
|
|||||||
fields = [] :: [#xdata_field{}]}).
|
fields = [] :: [#xdata_field{}]}).
|
||||||
-type xdata() :: #xdata{}.
|
-type xdata() :: #xdata{}.
|
||||||
|
|
||||||
|
-record(adhoc_command, {node :: binary(),
|
||||||
|
action = execute :: 'cancel' | 'complete' | 'execute' | 'next' | 'prev',
|
||||||
|
sid :: binary(),
|
||||||
|
status :: 'canceled' | 'completed' | 'executing',
|
||||||
|
lang :: binary(),
|
||||||
|
actions :: #adhoc_actions{},
|
||||||
|
notes = [] :: [#adhoc_note{}],
|
||||||
|
xdata :: #xdata{}}).
|
||||||
|
-type adhoc_command() :: #adhoc_command{}.
|
||||||
|
|
||||||
-record(search, {instructions :: binary(),
|
-record(search, {instructions :: binary(),
|
||||||
first :: binary(),
|
first :: binary(),
|
||||||
last :: binary(),
|
last :: binary(),
|
||||||
@ -799,6 +819,7 @@
|
|||||||
pubsub_options() |
|
pubsub_options() |
|
||||||
compress() |
|
compress() |
|
||||||
bytestreams() |
|
bytestreams() |
|
||||||
|
adhoc_actions() |
|
||||||
muc_history() |
|
muc_history() |
|
||||||
identity() |
|
identity() |
|
||||||
feature_csi() |
|
feature_csi() |
|
||||||
@ -810,9 +831,7 @@
|
|||||||
pubsub() |
|
pubsub() |
|
||||||
muc_owner() |
|
muc_owner() |
|
||||||
muc_actor() |
|
muc_actor() |
|
||||||
carbons_private() |
|
adhoc_note() |
|
||||||
mix_leave() |
|
|
||||||
muc_subscribe() |
|
|
||||||
rosterver_feature() |
|
rosterver_feature() |
|
||||||
muc_invite() |
|
muc_invite() |
|
||||||
vcard_xupdate() |
|
vcard_xupdate() |
|
||||||
@ -820,28 +839,16 @@
|
|||||||
bookmark_conference() |
|
bookmark_conference() |
|
||||||
offline() |
|
offline() |
|
||||||
time() |
|
time() |
|
||||||
muc_unique() |
|
|
||||||
sasl_response() |
|
|
||||||
pubsub_subscribe() |
|
|
||||||
presence() |
|
|
||||||
message() |
|
|
||||||
sm_enable() |
|
sm_enable() |
|
||||||
starttls_failure() |
|
starttls_failure() |
|
||||||
sasl_challenge() |
|
sasl_challenge() |
|
||||||
gone() |
|
|
||||||
x_conference() |
|
x_conference() |
|
||||||
private() |
|
private() |
|
||||||
compress_failure() |
|
compress_failure() |
|
||||||
sasl_failure() |
|
sasl_failure() |
|
||||||
bookmark_storage() |
|
bookmark_storage() |
|
||||||
vcard_name() |
|
vcard_name() |
|
||||||
sm_resume() |
|
|
||||||
carbons_enable() |
|
|
||||||
expire() |
|
|
||||||
muc_unsubscribe() |
|
|
||||||
pubsub_unsubscribe() |
|
|
||||||
muc_decline() |
|
muc_decline() |
|
||||||
chatstate() |
|
|
||||||
sasl_auth() |
|
sasl_auth() |
|
||||||
p1_push() |
|
p1_push() |
|
||||||
legacy_auth() |
|
legacy_auth() |
|
||||||
@ -866,10 +873,11 @@
|
|||||||
rsm_first() |
|
rsm_first() |
|
||||||
stat() |
|
stat() |
|
||||||
xdata_field() |
|
xdata_field() |
|
||||||
|
adhoc_command() |
|
||||||
sm_failed() |
|
sm_failed() |
|
||||||
ping() |
|
ping() |
|
||||||
disco_item() |
|
|
||||||
privacy_item() |
|
privacy_item() |
|
||||||
|
disco_item() |
|
||||||
caps() |
|
caps() |
|
||||||
muc() |
|
muc() |
|
||||||
stream_features() |
|
stream_features() |
|
||||||
@ -894,4 +902,19 @@
|
|||||||
error() |
|
error() |
|
||||||
stream_error() |
|
stream_error() |
|
||||||
muc_user() |
|
muc_user() |
|
||||||
vcard_adr().
|
vcard_adr() |
|
||||||
|
carbons_private() |
|
||||||
|
mix_leave() |
|
||||||
|
muc_subscribe() |
|
||||||
|
muc_unique() |
|
||||||
|
sasl_response() |
|
||||||
|
pubsub_subscribe() |
|
||||||
|
presence() |
|
||||||
|
message() |
|
||||||
|
gone() |
|
||||||
|
sm_resume() |
|
||||||
|
carbons_enable() |
|
||||||
|
expire() |
|
||||||
|
muc_unsubscribe() |
|
||||||
|
pubsub_unsubscribe() |
|
||||||
|
chatstate().
|
||||||
|
@ -31,18 +31,15 @@
|
|||||||
|
|
||||||
-behaviour(gen_mod).
|
-behaviour(gen_mod).
|
||||||
|
|
||||||
-export([start/2, stop/1, process_local_iq/3,
|
-export([start/2, stop/1, process_local_iq/1,
|
||||||
process_sm_iq/3, get_local_commands/5,
|
process_sm_iq/1, get_local_commands/5,
|
||||||
get_local_identity/5, get_local_features/5,
|
get_local_identity/5, get_local_features/5,
|
||||||
get_sm_commands/5, get_sm_identity/5, get_sm_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]).
|
||||||
|
|
||||||
-include("ejabberd.hrl").
|
-include("ejabberd.hrl").
|
||||||
-include("logger.hrl").
|
-include("logger.hrl").
|
||||||
|
-include("xmpp.hrl").
|
||||||
-include("jlib.hrl").
|
|
||||||
|
|
||||||
-include("adhoc.hrl").
|
|
||||||
|
|
||||||
start(Host, Opts) ->
|
start(Host, Opts) ->
|
||||||
IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1,
|
IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1,
|
||||||
@ -94,7 +91,7 @@ stop(Host) ->
|
|||||||
%-------------------------------------------------------------------------
|
%-------------------------------------------------------------------------
|
||||||
|
|
||||||
get_local_commands(Acc, _From,
|
get_local_commands(Acc, _From,
|
||||||
#jid{server = Server, lserver = LServer} = _To, <<"">>,
|
#jid{server = Server, lserver = LServer} = _To, undefined,
|
||||||
Lang) ->
|
Lang) ->
|
||||||
Display = gen_mod:get_module_opt(LServer, ?MODULE,
|
Display = gen_mod:get_module_opt(LServer, ?MODULE,
|
||||||
report_commands_node,
|
report_commands_node,
|
||||||
@ -107,12 +104,9 @@ get_local_commands(Acc, _From,
|
|||||||
{result, I} -> I;
|
{result, I} -> I;
|
||||||
_ -> []
|
_ -> []
|
||||||
end,
|
end,
|
||||||
Nodes = [#xmlel{name = <<"item">>,
|
Nodes = [#disco_item{jid = jid:make(Server),
|
||||||
attrs =
|
node = ?NS_COMMANDS,
|
||||||
[{<<"jid">>, Server}, {<<"node">>, ?NS_COMMANDS},
|
name = translate:translate(Lang, <<"Commands">>)}],
|
||||||
{<<"name">>,
|
|
||||||
translate:translate(Lang, <<"Commands">>)}],
|
|
||||||
children = []}],
|
|
||||||
{result, Items ++ Nodes}
|
{result, Items ++ Nodes}
|
||||||
end;
|
end;
|
||||||
get_local_commands(_Acc, From,
|
get_local_commands(_Acc, From,
|
||||||
@ -128,7 +122,7 @@ get_local_commands(Acc, _From, _To, _Node, _Lang) ->
|
|||||||
%-------------------------------------------------------------------------
|
%-------------------------------------------------------------------------
|
||||||
|
|
||||||
get_sm_commands(Acc, _From,
|
get_sm_commands(Acc, _From,
|
||||||
#jid{lserver = LServer} = To, <<"">>, Lang) ->
|
#jid{lserver = LServer} = To, undefined, Lang) ->
|
||||||
Display = gen_mod:get_module_opt(LServer, ?MODULE,
|
Display = gen_mod:get_module_opt(LServer, ?MODULE,
|
||||||
report_commands_node,
|
report_commands_node,
|
||||||
fun(B) when is_boolean(B) -> B end,
|
fun(B) when is_boolean(B) -> B end,
|
||||||
@ -140,13 +134,9 @@ get_sm_commands(Acc, _From,
|
|||||||
{result, I} -> I;
|
{result, I} -> I;
|
||||||
_ -> []
|
_ -> []
|
||||||
end,
|
end,
|
||||||
Nodes = [#xmlel{name = <<"item">>,
|
Nodes = [#disco_item{jid = To,
|
||||||
attrs =
|
node = ?NS_COMMANDS,
|
||||||
[{<<"jid">>, jid:to_string(To)},
|
name = translate:translate(Lang, <<"Commands">>)}],
|
||||||
{<<"node">>, ?NS_COMMANDS},
|
|
||||||
{<<"name">>,
|
|
||||||
translate:translate(Lang, <<"Commands">>)}],
|
|
||||||
children = []}],
|
|
||||||
{result, Items ++ Nodes}
|
{result, Items ++ Nodes}
|
||||||
end;
|
end;
|
||||||
get_sm_commands(_Acc, From,
|
get_sm_commands(_Acc, From,
|
||||||
@ -160,21 +150,14 @@ get_sm_commands(Acc, _From, _To, _Node, _Lang) -> Acc.
|
|||||||
%% On disco info request to the ad-hoc node, return automation/command-list.
|
%% On disco info request to the ad-hoc node, return automation/command-list.
|
||||||
get_local_identity(Acc, _From, _To, ?NS_COMMANDS,
|
get_local_identity(Acc, _From, _To, ?NS_COMMANDS,
|
||||||
Lang) ->
|
Lang) ->
|
||||||
[#xmlel{name = <<"identity">>,
|
[#identity{category = <<"automation">>,
|
||||||
attrs =
|
type = <<"command-list">>,
|
||||||
[{<<"category">>, <<"automation">>},
|
name = translate:translate(Lang, <<"Commands">>)}
|
||||||
{<<"type">>, <<"command-list">>},
|
|
||||||
{<<"name">>,
|
|
||||||
translate:translate(Lang, <<"Commands">>)}],
|
|
||||||
children = []}
|
|
||||||
| Acc];
|
| Acc];
|
||||||
get_local_identity(Acc, _From, _To, <<"ping">>, Lang) ->
|
get_local_identity(Acc, _From, _To, <<"ping">>, Lang) ->
|
||||||
[#xmlel{name = <<"identity">>,
|
[#identity{category = <<"automation">>,
|
||||||
attrs =
|
type = <<"command-node">>,
|
||||||
[{<<"category">>, <<"automation">>},
|
name = translate:translate(Lang, <<"Ping">>)}
|
||||||
{<<"type">>, <<"command-node">>},
|
|
||||||
{<<"name">>, translate:translate(Lang, <<"Ping">>)}],
|
|
||||||
children = []}
|
|
||||||
| Acc];
|
| Acc];
|
||||||
get_local_identity(Acc, _From, _To, _Node, _Lang) ->
|
get_local_identity(Acc, _From, _To, _Node, _Lang) ->
|
||||||
Acc.
|
Acc.
|
||||||
@ -183,13 +166,9 @@ get_local_identity(Acc, _From, _To, _Node, _Lang) ->
|
|||||||
|
|
||||||
%% On disco info request to the ad-hoc node, return automation/command-list.
|
%% On disco info request to the ad-hoc node, return automation/command-list.
|
||||||
get_sm_identity(Acc, _From, _To, ?NS_COMMANDS, Lang) ->
|
get_sm_identity(Acc, _From, _To, ?NS_COMMANDS, Lang) ->
|
||||||
[#xmlel{name = <<"identity">>,
|
[#identity{category = <<"automation">>,
|
||||||
attrs =
|
type = <<"command-list">>,
|
||||||
[{<<"category">>, <<"automation">>},
|
name = translate:translate(Lang, <<"Commands">>)}
|
||||||
{<<"type">>, <<"command-list">>},
|
|
||||||
{<<"name">>,
|
|
||||||
translate:translate(Lang, <<"Commands">>)}],
|
|
||||||
children = []}
|
|
||||||
| Acc];
|
| Acc];
|
||||||
get_sm_identity(Acc, _From, _To, _Node, _Lang) -> Acc.
|
get_sm_identity(Acc, _From, _To, _Node, _Lang) -> Acc.
|
||||||
|
|
||||||
@ -225,34 +204,29 @@ get_sm_features(Acc, _From, _To, _Node, _Lang) -> Acc.
|
|||||||
|
|
||||||
%-------------------------------------------------------------------------
|
%-------------------------------------------------------------------------
|
||||||
|
|
||||||
process_local_iq(From, To, IQ) ->
|
process_local_iq(IQ) ->
|
||||||
process_adhoc_request(From, To, IQ,
|
process_adhoc_request(IQ, adhoc_local_commands).
|
||||||
adhoc_local_commands).
|
|
||||||
|
|
||||||
process_sm_iq(From, To, IQ) ->
|
process_sm_iq(IQ) ->
|
||||||
process_adhoc_request(From, To, IQ, adhoc_sm_commands).
|
process_adhoc_request(IQ, adhoc_sm_commands).
|
||||||
|
|
||||||
process_adhoc_request(From, To,
|
process_adhoc_request(#iq{from = From, to = To,
|
||||||
#iq{sub_el = SubEl, lang = Lang} = IQ, Hook) ->
|
type = set, lang = Lang,
|
||||||
?DEBUG("About to parse ~p...", [IQ]),
|
sub_els = [#adhoc_command{} = SubEl]} = IQ, Hook) ->
|
||||||
case adhoc:parse_request(IQ) of
|
Host = To#jid.lserver,
|
||||||
{error, Error} ->
|
case ejabberd_hooks:run_fold(Hook, Host, empty, [From, To, SubEl]) of
|
||||||
IQ#iq{type = error, sub_el = [SubEl, Error]};
|
ignore ->
|
||||||
#adhoc_request{} = AdhocRequest ->
|
ignore;
|
||||||
Host = To#jid.lserver,
|
empty ->
|
||||||
case ejabberd_hooks:run_fold(Hook, Host, empty,
|
Txt = <<"No hook has processed this command">>,
|
||||||
[From, To, AdhocRequest])
|
xmpp:make_error(IQ, xmpp:err_item_not_found(Txt, Lang));
|
||||||
of
|
{error, Error} ->
|
||||||
ignore -> ignore;
|
xmpp:make_error(IQ, Error);
|
||||||
empty ->
|
Command ->
|
||||||
Txt = <<"No hook has processed this command">>,
|
xmpp:make_iq_result(IQ, Command)
|
||||||
IQ#iq{type = error,
|
end;
|
||||||
sub_el = [SubEl, ?ERRT_ITEM_NOT_FOUND(Lang, Txt)]};
|
process_adhoc_request(#iq{} = IQ, _Hooks) ->
|
||||||
{error, Error} ->
|
xmpp:make_error(IQ, xmpp:err_bad_request()).
|
||||||
IQ#iq{type = error, sub_el = [SubEl, Error]};
|
|
||||||
Command -> IQ#iq{type = result, sub_el = [Command]}
|
|
||||||
end
|
|
||||||
end.
|
|
||||||
|
|
||||||
ping_item(Acc, _From, #jid{server = Server} = _To,
|
ping_item(Acc, _From, #jid{server = Server} = _To,
|
||||||
Lang) ->
|
Lang) ->
|
||||||
@ -260,27 +234,25 @@ ping_item(Acc, _From, #jid{server = Server} = _To,
|
|||||||
{result, I} -> I;
|
{result, I} -> I;
|
||||||
_ -> []
|
_ -> []
|
||||||
end,
|
end,
|
||||||
Nodes = [#xmlel{name = <<"item">>,
|
Nodes = [#disco_item{jid = jid:make(Server),
|
||||||
attrs =
|
node = <<"ping">>,
|
||||||
[{<<"jid">>, Server}, {<<"node">>, <<"ping">>},
|
name = translate:translate(Lang, <<"Ping">>)}],
|
||||||
{<<"name">>, translate:translate(Lang, <<"Ping">>)}],
|
|
||||||
children = []}],
|
|
||||||
{result, Items ++ Nodes}.
|
{result, Items ++ Nodes}.
|
||||||
|
|
||||||
ping_command(_Acc, _From, _To,
|
ping_command(_Acc, _From, _To,
|
||||||
#adhoc_request{lang = Lang, node = <<"ping">>,
|
#adhoc_command{lang = Lang, node = <<"ping">>,
|
||||||
sessionid = _Sessionid, action = Action} =
|
action = Action} = Request) ->
|
||||||
Request) ->
|
if Action == execute ->
|
||||||
if Action == <<"">>; Action == <<"execute">> ->
|
xmpp_util:make_adhoc_response(
|
||||||
adhoc:produce_response(Request,
|
Request,
|
||||||
#adhoc_response{status = completed,
|
#adhoc_command{
|
||||||
notes =
|
status = completed,
|
||||||
[{<<"info">>,
|
notes = [#adhoc_note{
|
||||||
translate:translate(Lang,
|
type = info,
|
||||||
<<"Pong">>)}]});
|
data = translate:translate(Lang, <<"Pong">>)}]});
|
||||||
true ->
|
true ->
|
||||||
Txt = <<"Incorrect value of 'action' attribute">>,
|
Txt = <<"Incorrect value of 'action' attribute">>,
|
||||||
{error, ?ERRT_BAD_REQUEST(Lang, Txt)}
|
{error, xmpp:err_bad_request(Txt, Lang)}
|
||||||
end;
|
end;
|
||||||
ping_command(Acc, _From, _To, _Request) -> Acc.
|
ping_command(Acc, _From, _To, _Request) -> Acc.
|
||||||
|
|
||||||
|
@ -39,8 +39,7 @@
|
|||||||
|
|
||||||
-include("ejabberd.hrl").
|
-include("ejabberd.hrl").
|
||||||
-include("logger.hrl").
|
-include("logger.hrl").
|
||||||
-include("jlib.hrl").
|
-include("xmpp.hrl").
|
||||||
-include("adhoc.hrl").
|
|
||||||
-include("mod_announce.hrl").
|
-include("mod_announce.hrl").
|
||||||
|
|
||||||
-callback init(binary(), gen_mod:opts()) -> any().
|
-callback init(binary(), gen_mod:opts()) -> any().
|
||||||
@ -57,6 +56,7 @@
|
|||||||
-define(NS_ADMINL(Sub), [<<"http:">>, <<"jabber.org">>, <<"protocol">>,
|
-define(NS_ADMINL(Sub), [<<"http:">>, <<"jabber.org">>, <<"protocol">>,
|
||||||
<<"admin">>, <<Sub>>]).
|
<<"admin">>, <<Sub>>]).
|
||||||
|
|
||||||
|
tokenize(undefined) -> [];
|
||||||
tokenize(Node) -> str:tokens(Node, <<"/#">>).
|
tokenize(Node) -> str:tokens(Node, <<"/#">>).
|
||||||
|
|
||||||
start(Host, Opts) ->
|
start(Host, Opts) ->
|
||||||
@ -131,7 +131,7 @@ stop(Host) ->
|
|||||||
{wait, Proc}.
|
{wait, Proc}.
|
||||||
|
|
||||||
%% Announcing via messages to a custom resource
|
%% Announcing via messages to a custom resource
|
||||||
announce(From, #jid{luser = <<>>} = To, #xmlel{name = <<"message">>} = Packet) ->
|
announce(From, #jid{luser = <<>>} = To, #message{} = Packet) ->
|
||||||
Proc = gen_mod:get_module_proc(To#jid.lserver, ?PROCNAME),
|
Proc = gen_mod:get_module_proc(To#jid.lserver, ?PROCNAME),
|
||||||
case To#jid.lresource of
|
case To#jid.lresource of
|
||||||
<<"announce/all">> ->
|
<<"announce/all">> ->
|
||||||
@ -173,10 +173,9 @@ announce(_From, _To, _Packet) ->
|
|||||||
%%-------------------------------------------------------------------------
|
%%-------------------------------------------------------------------------
|
||||||
%% Announcing via ad-hoc commands
|
%% Announcing via ad-hoc commands
|
||||||
-define(INFO_COMMAND(Lang, Node),
|
-define(INFO_COMMAND(Lang, Node),
|
||||||
[#xmlel{name = <<"identity">>,
|
[#identity{category = <<"automation">>,
|
||||||
attrs = [{<<"category">>, <<"automation">>},
|
type = <<"command-node">>,
|
||||||
{<<"type">>, <<"command-node">>},
|
name = get_title(Lang, Node)}]).
|
||||||
{<<"name">>, get_title(Lang, Node)}]}]).
|
|
||||||
|
|
||||||
disco_identity(Acc, _From, _To, Node, Lang) ->
|
disco_identity(Acc, _From, _To, Node, Lang) ->
|
||||||
LNode = tokenize(Node),
|
LNode = tokenize(Node),
|
||||||
@ -210,7 +209,7 @@ disco_identity(Acc, _From, _To, Node, Lang) ->
|
|||||||
-define(INFO_RESULT(Allow, Feats, Lang),
|
-define(INFO_RESULT(Allow, Feats, Lang),
|
||||||
case Allow of
|
case Allow of
|
||||||
deny ->
|
deny ->
|
||||||
{error, ?ERRT_FORBIDDEN(Lang, <<"Denied by ACL">>)};
|
{error, xmpp:err_forbidden(<<"Denied by ACL">>, Lang)};
|
||||||
allow ->
|
allow ->
|
||||||
{result, Feats}
|
{result, Feats}
|
||||||
end).
|
end).
|
||||||
@ -226,7 +225,7 @@ disco_features(Acc, From, #jid{lserver = LServer} = _To, <<"announce">>, Lang) -
|
|||||||
acl:match_rule(global, Access2, From)} of
|
acl:match_rule(global, Access2, From)} of
|
||||||
{deny, deny} ->
|
{deny, deny} ->
|
||||||
Txt = <<"Denied by ACL">>,
|
Txt = <<"Denied by ACL">>,
|
||||||
{error, ?ERRT_FORBIDDEN(Lang, Txt)};
|
{error, xmpp:err_forbidden(Txt, Lang)};
|
||||||
_ ->
|
_ ->
|
||||||
{result, []}
|
{result, []}
|
||||||
end
|
end
|
||||||
@ -269,26 +268,19 @@ disco_features(Acc, From, #jid{lserver = LServer} = _To, Node, Lang) ->
|
|||||||
|
|
||||||
%%-------------------------------------------------------------------------
|
%%-------------------------------------------------------------------------
|
||||||
-define(NODE_TO_ITEM(Lang, Server, Node),
|
-define(NODE_TO_ITEM(Lang, Server, Node),
|
||||||
(
|
#disco_item{jid = jid:make(Server),
|
||||||
#xmlel{
|
node = Node,
|
||||||
name = <<"item">>,
|
name = get_title(Lang, Node)}).
|
||||||
attrs = [
|
|
||||||
{<<"jid">>, Server},
|
|
||||||
{<<"node">>, Node},
|
|
||||||
{<<"name">>, get_title(Lang, Node)}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
)).
|
|
||||||
|
|
||||||
-define(ITEMS_RESULT(Allow, Items, Lang),
|
-define(ITEMS_RESULT(Allow, Items, Lang),
|
||||||
case Allow of
|
case Allow of
|
||||||
deny ->
|
deny ->
|
||||||
{error, ?ERRT_FORBIDDEN(Lang, <<"Denied by ACL">>)};
|
{error, xmpp:err_forbidden(<<"Denied by ACL">>, Lang)};
|
||||||
allow ->
|
allow ->
|
||||||
{result, Items}
|
{result, Items}
|
||||||
end).
|
end).
|
||||||
|
|
||||||
disco_items(Acc, From, #jid{lserver = LServer, server = Server} = _To, <<>>, Lang) ->
|
disco_items(Acc, From, #jid{lserver = LServer, server = Server} = _To, undefined, Lang) ->
|
||||||
case gen_mod:is_loaded(LServer, mod_adhoc) of
|
case gen_mod:is_loaded(LServer, mod_adhoc) of
|
||||||
false ->
|
false ->
|
||||||
Acc;
|
Acc;
|
||||||
@ -393,15 +385,15 @@ announce_items(Acc, From, #jid{lserver = LServer, server = Server} = _To, Lang)
|
|||||||
commands_result(Allow, From, To, Request) ->
|
commands_result(Allow, From, To, Request) ->
|
||||||
case Allow of
|
case Allow of
|
||||||
deny ->
|
deny ->
|
||||||
Lang = Request#adhoc_request.lang,
|
Lang = Request#adhoc_command.lang,
|
||||||
{error, ?ERRT_FORBIDDEN(Lang, <<"Denied by ACL">>)};
|
{error, xmpp:err_forbidden(<<"Denied by ACL">>, Lang)};
|
||||||
allow ->
|
allow ->
|
||||||
announce_commands(From, To, Request)
|
announce_commands(From, To, Request)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
||||||
announce_commands(Acc, From, #jid{lserver = LServer} = To,
|
announce_commands(Acc, From, #jid{lserver = LServer} = To,
|
||||||
#adhoc_request{ node = Node} = Request) ->
|
#adhoc_command{node = Node} = Request) ->
|
||||||
LNode = tokenize(Node),
|
LNode = tokenize(Node),
|
||||||
F = fun() ->
|
F = fun() ->
|
||||||
Access = get_access(global),
|
Access = get_access(global),
|
||||||
@ -440,59 +432,35 @@ announce_commands(Acc, From, #jid{lserver = LServer} = To,
|
|||||||
%%-------------------------------------------------------------------------
|
%%-------------------------------------------------------------------------
|
||||||
|
|
||||||
announce_commands(From, To,
|
announce_commands(From, To,
|
||||||
#adhoc_request{lang = Lang,
|
#adhoc_command{lang = Lang,
|
||||||
node = Node,
|
node = Node,
|
||||||
action = Action,
|
sid = SID,
|
||||||
xdata = XData} = Request) ->
|
xdata = XData,
|
||||||
%% If the "action" attribute is not present, it is
|
action = Action} = Request) ->
|
||||||
%% understood as "execute". If there was no <actions/>
|
ActionIsExecute = Action == execute orelse Action == complete,
|
||||||
%% element in the first response (which there isn't in our
|
if Action == cancel ->
|
||||||
%% case), "execute" and "complete" are equivalent.
|
|
||||||
ActionIsExecute = lists:member(Action, [<<>>, <<"execute">>, <<"complete">>]),
|
|
||||||
if Action == <<"cancel">> ->
|
|
||||||
%% User cancels request
|
%% User cancels request
|
||||||
adhoc:produce_response(Request, #adhoc_response{status = canceled});
|
#adhoc_command{status = canceled, lang = Lang, node = Node,
|
||||||
XData == false, ActionIsExecute ->
|
sid = SID};
|
||||||
|
XData == undefined, ActionIsExecute ->
|
||||||
%% User requests form
|
%% User requests form
|
||||||
Elements = generate_adhoc_form(Lang, Node, To#jid.lserver),
|
Form = generate_adhoc_form(Lang, Node, To#jid.lserver),
|
||||||
adhoc:produce_response(Request,
|
#adhoc_command{status = executing, lang = Lang, node = Node,
|
||||||
#adhoc_response{status = executing,elements = [Elements]});
|
sid = SID, xdata = Form};
|
||||||
XData /= false, ActionIsExecute ->
|
XData /= undefined, ActionIsExecute ->
|
||||||
%% User returns form.
|
handle_adhoc_form(From, To, Request);
|
||||||
case jlib:parse_xdata_submit(XData) of
|
|
||||||
invalid ->
|
|
||||||
{error, ?ERRT_BAD_REQUEST(Lang, <<"Incorrect data form">>)};
|
|
||||||
Fields ->
|
|
||||||
handle_adhoc_form(From, To, Request, Fields)
|
|
||||||
end;
|
|
||||||
true ->
|
true ->
|
||||||
Txt = <<"Incorrect action or data form">>,
|
Txt = <<"Unexpected action">>,
|
||||||
{error, ?ERRT_BAD_REQUEST(Lang, Txt)}
|
{error, xmpp:err_bad_request(Txt, Lang)}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
-define(VVALUE(Val),
|
|
||||||
(
|
|
||||||
#xmlel{
|
|
||||||
name = <<"value">>,
|
|
||||||
children = [{xmlcdata, Val}]
|
|
||||||
}
|
|
||||||
)).
|
|
||||||
|
|
||||||
-define(TVFIELD(Type, Var, Val),
|
-define(TVFIELD(Type, Var, Val),
|
||||||
(
|
#xdata_field{type = Type, var = Var, values = vvaluel(Val)}).
|
||||||
#xmlel{
|
|
||||||
name = <<"field">>,
|
|
||||||
attrs = [{<<"type">>, Type}, {<<"var">>, Var}],
|
|
||||||
children = vvaluel(Val)
|
|
||||||
}
|
|
||||||
)).
|
|
||||||
|
|
||||||
-define(HFIELD(), ?TVFIELD(<<"hidden">>, <<"FORM_TYPE">>, ?NS_ADMIN)).
|
|
||||||
|
|
||||||
vvaluel(Val) ->
|
vvaluel(Val) ->
|
||||||
case Val of
|
case Val of
|
||||||
<<>> -> [];
|
<<>> -> [];
|
||||||
_ -> [?VVALUE(Val)]
|
_ -> [Val]
|
||||||
end.
|
end.
|
||||||
|
|
||||||
generate_adhoc_form(Lang, Node, ServerHost) ->
|
generate_adhoc_form(Lang, Node, ServerHost) ->
|
||||||
@ -503,49 +471,27 @@ generate_adhoc_form(Lang, Node, ServerHost) ->
|
|||||||
true ->
|
true ->
|
||||||
{<<>>, <<>>}
|
{<<>>, <<>>}
|
||||||
end,
|
end,
|
||||||
#xmlel{
|
Fs = if (LNode == ?NS_ADMINL("delete-motd"))
|
||||||
name = <<"x">>,
|
or (LNode == ?NS_ADMINL("delete-motd-allhosts")) ->
|
||||||
attrs = [{<<"xmlns">>, ?NS_XDATA}, {<<"type">>, <<"form">>}],
|
[#xdata_field{type = boolean,
|
||||||
children = [
|
var = <<"confirm">>,
|
||||||
?HFIELD(),
|
label = translate:translate(
|
||||||
#xmlel{name = <<"title">>, children = [{xmlcdata, get_title(Lang, Node)}]}
|
Lang, <<"Really delete message of the day?">>),
|
||||||
]
|
values = [<<"true">>]}];
|
||||||
++
|
true ->
|
||||||
if (LNode == ?NS_ADMINL("delete-motd"))
|
[#xdata_field{type = 'text-single',
|
||||||
or (LNode == ?NS_ADMINL("delete-motd-allhosts")) ->
|
var = <<"subject">>,
|
||||||
[#xmlel{
|
label = translate:translate(Lang, <<"Subject">>),
|
||||||
name = <<"field">>,
|
values = vvaluel(OldSubject)},
|
||||||
attrs = [
|
#xdata_field{type = 'text-multi',
|
||||||
{<<"var">>, <<"confirm">>},
|
var = <<"body">>,
|
||||||
{<<"type">>, <<"boolean">>},
|
label = translate:translate(Lang, <<"Message body">>),
|
||||||
{<<"label">>,
|
values = vvaluel(OldBody)}]
|
||||||
translate:translate(Lang, <<"Really delete message of the day?">>)}
|
end,
|
||||||
],
|
#xdata{type = form,
|
||||||
children = [
|
title = get_title(Lang, Node),
|
||||||
#xmlel{name = <<"value">>, children = [{xmlcdata, <<"true">>}]}
|
fields = [#xdata_field{type = hidden, var = <<"FORM_TYPE">>,
|
||||||
]
|
values = [?NS_ADMIN]}|Fs]}.
|
||||||
}
|
|
||||||
];
|
|
||||||
true ->
|
|
||||||
[#xmlel{
|
|
||||||
name = <<"field">>,
|
|
||||||
attrs = [
|
|
||||||
{<<"var">>, <<"subject">>},
|
|
||||||
{<<"type">>, <<"text-single">>},
|
|
||||||
{<<"label">>, translate:translate(Lang, <<"Subject">>)}],
|
|
||||||
children = vvaluel(OldSubject)
|
|
||||||
},
|
|
||||||
#xmlel{
|
|
||||||
name = <<"field">>,
|
|
||||||
attrs = [
|
|
||||||
{<<"var">>, <<"body">>},
|
|
||||||
{<<"type">>, <<"text-multi">>},
|
|
||||||
{<<"label">>, translate:translate(Lang, <<"Message body">>)}],
|
|
||||||
children = vvaluel(OldBody)
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
end}.
|
|
||||||
|
|
||||||
join_lines([]) ->
|
join_lines([]) ->
|
||||||
<<>>;
|
<<>>;
|
||||||
@ -558,103 +504,73 @@ join_lines([], Acc) ->
|
|||||||
iolist_to_binary(lists:reverse(tl(Acc))).
|
iolist_to_binary(lists:reverse(tl(Acc))).
|
||||||
|
|
||||||
handle_adhoc_form(From, #jid{lserver = LServer} = To,
|
handle_adhoc_form(From, #jid{lserver = LServer} = To,
|
||||||
#adhoc_request{lang = Lang,
|
#adhoc_command{lang = Lang, node = Node,
|
||||||
node = Node,
|
sid = SessionID, xdata = XData}) ->
|
||||||
sessionid = SessionID},
|
Confirm = case xmpp_util:get_xdata_values(<<"confirm">>, XData) of
|
||||||
Fields) ->
|
[<<"true">>] -> true;
|
||||||
Confirm = case lists:keysearch(<<"confirm">>, 1, Fields) of
|
[<<"1">>] -> true;
|
||||||
{value, {<<"confirm">>, [<<"true">>]}} ->
|
_ -> false
|
||||||
true;
|
|
||||||
{value, {<<"confirm">>, [<<"1">>]}} ->
|
|
||||||
true;
|
|
||||||
_ ->
|
|
||||||
false
|
|
||||||
end,
|
end,
|
||||||
Subject = case lists:keysearch(<<"subject">>, 1, Fields) of
|
Subject = join_lines(xmpp_util:get_xdata_values(<<"subject">>, XData)),
|
||||||
{value, {<<"subject">>, SubjectLines}} ->
|
Body = join_lines(xmpp_util:get_xdata_values(<<"body">>, XData)),
|
||||||
%% There really shouldn't be more than one
|
Response = #adhoc_command{lang = Lang, node = Node, sid = SessionID,
|
||||||
%% subject line, but can we stop them?
|
status = completed},
|
||||||
join_lines(SubjectLines);
|
Packet = #message{type = headline,
|
||||||
_ ->
|
body = xmpp:mk_text(Body),
|
||||||
<<>>
|
subject = xmpp:mk_text(Subject)},
|
||||||
end,
|
|
||||||
Body = case lists:keysearch(<<"body">>, 1, Fields) of
|
|
||||||
{value, {<<"body">>, BodyLines}} ->
|
|
||||||
join_lines(BodyLines);
|
|
||||||
_ ->
|
|
||||||
<<>>
|
|
||||||
end,
|
|
||||||
Response = #adhoc_response{lang = Lang,
|
|
||||||
node = Node,
|
|
||||||
sessionid = SessionID,
|
|
||||||
status = completed},
|
|
||||||
Packet = #xmlel{
|
|
||||||
name = <<"message">>,
|
|
||||||
attrs = [{<<"type">>, <<"headline">>}],
|
|
||||||
children = if Subject /= <<>> ->
|
|
||||||
[#xmlel{name = <<"subject">>, children = [{xmlcdata, Subject}]}];
|
|
||||||
true ->
|
|
||||||
[]
|
|
||||||
end
|
|
||||||
++
|
|
||||||
if Body /= <<>> ->
|
|
||||||
[#xmlel{name = <<"body">>, children = [{xmlcdata, Body}]}];
|
|
||||||
true ->
|
|
||||||
[]
|
|
||||||
end
|
|
||||||
},
|
|
||||||
Proc = gen_mod:get_module_proc(LServer, ?PROCNAME),
|
Proc = gen_mod:get_module_proc(LServer, ?PROCNAME),
|
||||||
case {Node, Body} of
|
case {Node, Body} of
|
||||||
{?NS_ADMIN_DELETE_MOTD, _} ->
|
{?NS_ADMIN_DELETE_MOTD, _} ->
|
||||||
if Confirm ->
|
if Confirm ->
|
||||||
Proc ! {announce_motd_delete, From, To, Packet},
|
Proc ! {announce_motd_delete, From, To, Packet},
|
||||||
adhoc:produce_response(Response);
|
Response;
|
||||||
true ->
|
true ->
|
||||||
adhoc:produce_response(Response)
|
Response
|
||||||
end;
|
end;
|
||||||
{?NS_ADMIN_DELETE_MOTD_ALLHOSTS, _} ->
|
{?NS_ADMIN_DELETE_MOTD_ALLHOSTS, _} ->
|
||||||
if Confirm ->
|
if Confirm ->
|
||||||
Proc ! {announce_all_hosts_motd_delete, From, To, Packet},
|
Proc ! {announce_all_hosts_motd_delete, From, To, Packet},
|
||||||
adhoc:produce_response(Response);
|
Response;
|
||||||
true ->
|
true ->
|
||||||
adhoc:produce_response(Response)
|
Response
|
||||||
end;
|
end;
|
||||||
{_, <<>>} ->
|
{_, <<>>} ->
|
||||||
%% An announce message with no body is definitely an operator error.
|
%% An announce message with no body is definitely an operator error.
|
||||||
%% Throw an error and give him/her a chance to send message again.
|
%% Throw an error and give him/her a chance to send message again.
|
||||||
{error, ?ERRT_NOT_ACCEPTABLE(Lang,
|
{error, xmpp:err_not_acceptable(
|
||||||
<<"No body provided for announce message">>)};
|
<<"No body provided for announce message">>, Lang)};
|
||||||
%% Now send the packet to ?PROCNAME.
|
%% Now send the packet to ?PROCNAME.
|
||||||
%% We don't use direct announce_* functions because it
|
%% We don't use direct announce_* functions because it
|
||||||
%% leads to large delay in response and <iq/> queries processing
|
%% leads to large delay in response and <iq/> queries processing
|
||||||
{?NS_ADMIN_ANNOUNCE, _} ->
|
{?NS_ADMIN_ANNOUNCE, _} ->
|
||||||
Proc ! {announce_online, From, To, Packet},
|
Proc ! {announce_online, From, To, Packet},
|
||||||
adhoc:produce_response(Response);
|
Response;
|
||||||
{?NS_ADMIN_ANNOUNCE_ALLHOSTS, _} ->
|
{?NS_ADMIN_ANNOUNCE_ALLHOSTS, _} ->
|
||||||
Proc ! {announce_all_hosts_online, From, To, Packet},
|
Proc ! {announce_all_hosts_online, From, To, Packet},
|
||||||
adhoc:produce_response(Response);
|
Response;
|
||||||
{?NS_ADMIN_ANNOUNCE_ALL, _} ->
|
{?NS_ADMIN_ANNOUNCE_ALL, _} ->
|
||||||
Proc ! {announce_all, From, To, Packet},
|
Proc ! {announce_all, From, To, Packet},
|
||||||
adhoc:produce_response(Response);
|
Response;
|
||||||
{?NS_ADMIN_ANNOUNCE_ALL_ALLHOSTS, _} ->
|
{?NS_ADMIN_ANNOUNCE_ALL_ALLHOSTS, _} ->
|
||||||
Proc ! {announce_all_hosts_all, From, To, Packet},
|
Proc ! {announce_all_hosts_all, From, To, Packet},
|
||||||
adhoc:produce_response(Response);
|
Response;
|
||||||
{?NS_ADMIN_SET_MOTD, _} ->
|
{?NS_ADMIN_SET_MOTD, _} ->
|
||||||
Proc ! {announce_motd, From, To, Packet},
|
Proc ! {announce_motd, From, To, Packet},
|
||||||
adhoc:produce_response(Response);
|
Response;
|
||||||
{?NS_ADMIN_SET_MOTD_ALLHOSTS, _} ->
|
{?NS_ADMIN_SET_MOTD_ALLHOSTS, _} ->
|
||||||
Proc ! {announce_all_hosts_motd, From, To, Packet},
|
Proc ! {announce_all_hosts_motd, From, To, Packet},
|
||||||
adhoc:produce_response(Response);
|
Response;
|
||||||
{?NS_ADMIN_EDIT_MOTD, _} ->
|
{?NS_ADMIN_EDIT_MOTD, _} ->
|
||||||
Proc ! {announce_motd_update, From, To, Packet},
|
Proc ! {announce_motd_update, From, To, Packet},
|
||||||
adhoc:produce_response(Response);
|
Response;
|
||||||
{?NS_ADMIN_EDIT_MOTD_ALLHOSTS, _} ->
|
{?NS_ADMIN_EDIT_MOTD_ALLHOSTS, _} ->
|
||||||
Proc ! {announce_all_hosts_motd_update, From, To, Packet},
|
Proc ! {announce_all_hosts_motd_update, From, To, Packet},
|
||||||
adhoc:produce_response(Response);
|
Response;
|
||||||
_ ->
|
Junk ->
|
||||||
%% This can't happen, as we haven't registered any other
|
%% This can't happen, as we haven't registered any other
|
||||||
%% command nodes.
|
%% command nodes.
|
||||||
{error, ?ERR_INTERNAL_SERVER_ERROR}
|
?ERROR_MSG("got unexpected node/body = ~p", [Junk]),
|
||||||
|
{error, xmpp:err_internal_server_error()}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
get_title(Lang, <<"announce">>) ->
|
get_title(Lang, <<"announce">>) ->
|
||||||
@ -687,15 +603,15 @@ announce_all(From, To, Packet) ->
|
|||||||
Access = get_access(Host),
|
Access = get_access(Host),
|
||||||
case acl:match_rule(Host, Access, From) of
|
case acl:match_rule(Host, Access, From) of
|
||||||
deny ->
|
deny ->
|
||||||
Lang = fxml:get_tag_attr_s(<<"xml:lang">>, Packet),
|
Lang = xmpp:get_lang(Packet),
|
||||||
Txt = <<"Denied by ACL">>,
|
Txt = <<"Denied by ACL">>,
|
||||||
Err = jlib:make_error_reply(Packet, ?ERRT_FORBIDDEN(Lang, Txt)),
|
Err = xmpp:make_error(Packet, xmpp:err_forbidden(Txt, Lang)),
|
||||||
ejabberd_router:route(To, From, Err);
|
ejabberd_router:route(To, From, Err);
|
||||||
allow ->
|
allow ->
|
||||||
Local = jid:make(<<>>, To#jid.server, <<>>),
|
Local = jid:make(To#jid.server),
|
||||||
lists:foreach(
|
lists:foreach(
|
||||||
fun({User, Server}) ->
|
fun({User, Server}) ->
|
||||||
Dest = jid:make(User, Server, <<>>),
|
Dest = jid:make(User, Server),
|
||||||
ejabberd_router:route(Local, Dest, Packet)
|
ejabberd_router:route(Local, Dest, Packet)
|
||||||
end, ejabberd_auth:get_vh_registered_users(Host))
|
end, ejabberd_auth:get_vh_registered_users(Host))
|
||||||
end.
|
end.
|
||||||
@ -704,15 +620,15 @@ announce_all_hosts_all(From, To, Packet) ->
|
|||||||
Access = get_access(global),
|
Access = get_access(global),
|
||||||
case acl:match_rule(global, Access, From) of
|
case acl:match_rule(global, Access, From) of
|
||||||
deny ->
|
deny ->
|
||||||
Lang = fxml:get_tag_attr_s(<<"xml:lang">>, Packet),
|
Lang = xmpp:get_lang(Packet),
|
||||||
Txt = <<"Denied by ACL">>,
|
Txt = <<"Denied by ACL">>,
|
||||||
Err = jlib:make_error_reply(Packet, ?ERRT_FORBIDDEN(Lang, Txt)),
|
Err = xmpp:make_error(Packet, xmpp:err_forbidden(Txt, Lang)),
|
||||||
ejabberd_router:route(To, From, Err);
|
ejabberd_router:route(To, From, Err);
|
||||||
allow ->
|
allow ->
|
||||||
Local = jid:make(<<>>, To#jid.server, <<>>),
|
Local = jid:make(To#jid.server),
|
||||||
lists:foreach(
|
lists:foreach(
|
||||||
fun({User, Server}) ->
|
fun({User, Server}) ->
|
||||||
Dest = jid:make(User, Server, <<>>),
|
Dest = jid:make(User, Server),
|
||||||
ejabberd_router:route(Local, Dest, Packet)
|
ejabberd_router:route(Local, Dest, Packet)
|
||||||
end, ejabberd_auth:dirty_get_registered_users())
|
end, ejabberd_auth:dirty_get_registered_users())
|
||||||
end.
|
end.
|
||||||
@ -722,9 +638,9 @@ announce_online(From, To, Packet) ->
|
|||||||
Access = get_access(Host),
|
Access = get_access(Host),
|
||||||
case acl:match_rule(Host, Access, From) of
|
case acl:match_rule(Host, Access, From) of
|
||||||
deny ->
|
deny ->
|
||||||
Lang = fxml:get_tag_attr_s(<<"xml:lang">>, Packet),
|
Lang = xmpp:get_lang(Packet),
|
||||||
Txt = <<"Denied by ACL">>,
|
Txt = <<"Denied by ACL">>,
|
||||||
Err = jlib:make_error_reply(Packet, ?ERRT_FORBIDDEN(Lang, Txt)),
|
Err = xmpp:make_error(Packet, xmpp:err_forbidden(Txt, Lang)),
|
||||||
ejabberd_router:route(To, From, Err);
|
ejabberd_router:route(To, From, Err);
|
||||||
allow ->
|
allow ->
|
||||||
announce_online1(ejabberd_sm:get_vh_session_list(Host),
|
announce_online1(ejabberd_sm:get_vh_session_list(Host),
|
||||||
@ -736,9 +652,9 @@ announce_all_hosts_online(From, To, Packet) ->
|
|||||||
Access = get_access(global),
|
Access = get_access(global),
|
||||||
case acl:match_rule(global, Access, From) of
|
case acl:match_rule(global, Access, From) of
|
||||||
deny ->
|
deny ->
|
||||||
Lang = fxml:get_tag_attr_s(<<"xml:lang">>, Packet),
|
Lang = xmpp:get_lang(Packet),
|
||||||
Txt = <<"Denied by ACL">>,
|
Txt = <<"Denied by ACL">>,
|
||||||
Err = jlib:make_error_reply(Packet, ?ERRT_FORBIDDEN(Lang, Txt)),
|
Err = xmpp:make_error(Packet, xmpp:err_forbidden(Txt, Lang)),
|
||||||
ejabberd_router:route(To, From, Err);
|
ejabberd_router:route(To, From, Err);
|
||||||
allow ->
|
allow ->
|
||||||
announce_online1(ejabberd_sm:dirty_get_sessions_list(),
|
announce_online1(ejabberd_sm:dirty_get_sessions_list(),
|
||||||
@ -747,7 +663,7 @@ announce_all_hosts_online(From, To, Packet) ->
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
announce_online1(Sessions, Server, Packet) ->
|
announce_online1(Sessions, Server, Packet) ->
|
||||||
Local = jid:make(<<>>, Server, <<>>),
|
Local = jid:make(Server),
|
||||||
lists:foreach(
|
lists:foreach(
|
||||||
fun({U, S, R}) ->
|
fun({U, S, R}) ->
|
||||||
Dest = jid:make(U, S, R),
|
Dest = jid:make(U, S, R),
|
||||||
@ -759,9 +675,9 @@ announce_motd(From, To, Packet) ->
|
|||||||
Access = get_access(Host),
|
Access = get_access(Host),
|
||||||
case acl:match_rule(Host, Access, From) of
|
case acl:match_rule(Host, Access, From) of
|
||||||
deny ->
|
deny ->
|
||||||
Lang = fxml:get_tag_attr_s(<<"xml:lang">>, Packet),
|
Lang = xmpp:get_lang(Packet),
|
||||||
Txt = <<"Denied by ACL">>,
|
Txt = <<"Denied by ACL">>,
|
||||||
Err = jlib:make_error_reply(Packet, ?ERRT_FORBIDDEN(Lang, Txt)),
|
Err = xmpp:make_error(Packet, xmpp:err_forbidden(Txt, Lang)),
|
||||||
ejabberd_router:route(To, From, Err);
|
ejabberd_router:route(To, From, Err);
|
||||||
allow ->
|
allow ->
|
||||||
announce_motd(Host, Packet)
|
announce_motd(Host, Packet)
|
||||||
@ -771,9 +687,9 @@ announce_all_hosts_motd(From, To, Packet) ->
|
|||||||
Access = get_access(global),
|
Access = get_access(global),
|
||||||
case acl:match_rule(global, Access, From) of
|
case acl:match_rule(global, Access, From) of
|
||||||
deny ->
|
deny ->
|
||||||
Lang = fxml:get_tag_attr_s(<<"xml:lang">>, Packet),
|
Lang = xmpp:get_lang(Packet),
|
||||||
Txt = <<"Denied by ACL">>,
|
Txt = <<"Denied by ACL">>,
|
||||||
Err = jlib:make_error_reply(Packet, ?ERRT_FORBIDDEN(Lang, Txt)),
|
Err = xmpp:make_error(Packet, xmpp:err_forbidden(Txt, Lang)),
|
||||||
ejabberd_router:route(To, From, Err);
|
ejabberd_router:route(To, From, Err);
|
||||||
allow ->
|
allow ->
|
||||||
Hosts = ?MYHOSTS,
|
Hosts = ?MYHOSTS,
|
||||||
@ -793,9 +709,9 @@ announce_motd_update(From, To, Packet) ->
|
|||||||
Access = get_access(Host),
|
Access = get_access(Host),
|
||||||
case acl:match_rule(Host, Access, From) of
|
case acl:match_rule(Host, Access, From) of
|
||||||
deny ->
|
deny ->
|
||||||
Lang = fxml:get_tag_attr_s(<<"xml:lang">>, Packet),
|
Lang = xmpp:get_lang(Packet),
|
||||||
Txt = <<"Denied by ACL">>,
|
Txt = <<"Denied by ACL">>,
|
||||||
Err = jlib:make_error_reply(Packet, ?ERRT_FORBIDDEN(Lang, Txt)),
|
Err = xmpp:make_error(Packet, xmpp:err_forbidden(Txt, Lang)),
|
||||||
ejabberd_router:route(To, From, Err);
|
ejabberd_router:route(To, From, Err);
|
||||||
allow ->
|
allow ->
|
||||||
announce_motd_update(Host, Packet)
|
announce_motd_update(Host, Packet)
|
||||||
@ -805,9 +721,9 @@ announce_all_hosts_motd_update(From, To, Packet) ->
|
|||||||
Access = get_access(global),
|
Access = get_access(global),
|
||||||
case acl:match_rule(global, Access, From) of
|
case acl:match_rule(global, Access, From) of
|
||||||
deny ->
|
deny ->
|
||||||
Lang = fxml:get_tag_attr_s(<<"xml:lang">>, Packet),
|
Lang = xmpp:get_lang(Packet),
|
||||||
Txt = <<"Denied by ACL">>,
|
Txt = <<"Denied by ACL">>,
|
||||||
Err = jlib:make_error_reply(Packet, ?ERRT_FORBIDDEN(Lang, Txt)),
|
Err = xmpp:make_error(Packet, xmpp:err_forbidden(Txt, Lang)),
|
||||||
ejabberd_router:route(To, From, Err);
|
ejabberd_router:route(To, From, Err);
|
||||||
allow ->
|
allow ->
|
||||||
Hosts = ?MYHOSTS,
|
Hosts = ?MYHOSTS,
|
||||||
@ -817,16 +733,16 @@ announce_all_hosts_motd_update(From, To, Packet) ->
|
|||||||
announce_motd_update(LServer, Packet) ->
|
announce_motd_update(LServer, Packet) ->
|
||||||
announce_motd_delete(LServer),
|
announce_motd_delete(LServer),
|
||||||
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
||||||
Mod:set_motd(LServer, Packet).
|
Mod:set_motd(LServer, xmpp:encode(Packet)).
|
||||||
|
|
||||||
announce_motd_delete(From, To, Packet) ->
|
announce_motd_delete(From, To, Packet) ->
|
||||||
Host = To#jid.lserver,
|
Host = To#jid.lserver,
|
||||||
Access = get_access(Host),
|
Access = get_access(Host),
|
||||||
case acl:match_rule(Host, Access, From) of
|
case acl:match_rule(Host, Access, From) of
|
||||||
deny ->
|
deny ->
|
||||||
Lang = fxml:get_tag_attr_s(<<"xml:lang">>, Packet),
|
Lang = xmpp:get_lang(Packet),
|
||||||
Txt = <<"Denied by ACL">>,
|
Txt = <<"Denied by ACL">>,
|
||||||
Err = jlib:make_error_reply(Packet, ?ERRT_FORBIDDEN(Lang, Txt)),
|
Err = xmpp:make_error(Packet, xmpp:err_forbidden(Txt, Lang)),
|
||||||
ejabberd_router:route(To, From, Err);
|
ejabberd_router:route(To, From, Err);
|
||||||
allow ->
|
allow ->
|
||||||
announce_motd_delete(Host)
|
announce_motd_delete(Host)
|
||||||
@ -836,9 +752,9 @@ announce_all_hosts_motd_delete(From, To, Packet) ->
|
|||||||
Access = get_access(global),
|
Access = get_access(global),
|
||||||
case acl:match_rule(global, Access, From) of
|
case acl:match_rule(global, Access, From) of
|
||||||
deny ->
|
deny ->
|
||||||
Lang = fxml:get_tag_attr_s(<<"xml:lang">>, Packet),
|
Lang = xmpp:get_lang(Packet),
|
||||||
Txt = <<"Denied by ACL">>,
|
Txt = <<"Denied by ACL">>,
|
||||||
Err = jlib:make_error_reply(Packet, ?ERRT_FORBIDDEN(Lang, Txt)),
|
Err = xmpp:make_error(Packet, xmpp:err_forbidden(Txt, Lang)),
|
||||||
ejabberd_router:route(To, From, Err);
|
ejabberd_router:route(To, From, Err);
|
||||||
allow ->
|
allow ->
|
||||||
Hosts = ?MYHOSTS,
|
Hosts = ?MYHOSTS,
|
||||||
@ -853,13 +769,19 @@ send_motd(#jid{luser = LUser, lserver = LServer} = JID) when LUser /= <<>> ->
|
|||||||
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
||||||
case Mod:get_motd(LServer) of
|
case Mod:get_motd(LServer) of
|
||||||
{ok, Packet} ->
|
{ok, Packet} ->
|
||||||
case Mod:is_motd_user(LUser, LServer) of
|
try xmpp:decode(Packet, [ignore_els]) of
|
||||||
false ->
|
Msg ->
|
||||||
Local = jid:make(<<>>, LServer, <<>>),
|
case Mod:is_motd_user(LUser, LServer) of
|
||||||
ejabberd_router:route(Local, JID, Packet),
|
false ->
|
||||||
Mod:set_motd_user(LUser, LServer);
|
Local = jid:make(LServer),
|
||||||
true ->
|
ejabberd_router:route(Local, JID, Msg),
|
||||||
ok
|
Mod:set_motd_user(LUser, LServer);
|
||||||
|
true ->
|
||||||
|
ok
|
||||||
|
end
|
||||||
|
catch _:{xmpp_codec, Why} ->
|
||||||
|
?ERROR_MSG("failed to decode motd packet ~p: ~s",
|
||||||
|
[Packet, xmpp:format_error(Why)])
|
||||||
end;
|
end;
|
||||||
error ->
|
error ->
|
||||||
ok
|
ok
|
||||||
@ -871,31 +793,24 @@ get_stored_motd(LServer) ->
|
|||||||
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
||||||
case Mod:get_motd(LServer) of
|
case Mod:get_motd(LServer) of
|
||||||
{ok, Packet} ->
|
{ok, Packet} ->
|
||||||
{fxml:get_subtag_cdata(Packet, <<"subject">>),
|
try xmpp:decode(Packet, [ignore_els]) of
|
||||||
fxml:get_subtag_cdata(Packet, <<"body">>)};
|
#message{body = Body, subject = Subject} ->
|
||||||
|
{xmpp:get_text(Subject), xmpp:get_text(Body)}
|
||||||
|
catch _:{xmpp_codec, Why} ->
|
||||||
|
?ERROR_MSG("failed to decode motd packet ~p: ~s",
|
||||||
|
[Packet, xmpp:format_error(Why)])
|
||||||
|
end;
|
||||||
error ->
|
error ->
|
||||||
{<<>>, <<>>}
|
{<<>>, <<>>}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
%% This function is similar to others, but doesn't perform any ACL verification
|
%% This function is similar to others, but doesn't perform any ACL verification
|
||||||
send_announcement_to_all(Host, SubjectS, BodyS) ->
|
send_announcement_to_all(Host, SubjectS, BodyS) ->
|
||||||
SubjectEls = if SubjectS /= <<>> ->
|
Packet = #message{type = headline,
|
||||||
[#xmlel{name = <<"subject">>, children = [{xmlcdata, SubjectS}]}];
|
body = xmpp:mk_text(BodyS),
|
||||||
true ->
|
subject = xmpp:mk_text(SubjectS)},
|
||||||
[]
|
|
||||||
end,
|
|
||||||
BodyEls = if BodyS /= <<>> ->
|
|
||||||
[#xmlel{name = <<"body">>, children = [{xmlcdata, BodyS}]}];
|
|
||||||
true ->
|
|
||||||
[]
|
|
||||||
end,
|
|
||||||
Packet = #xmlel{
|
|
||||||
name = <<"message">>,
|
|
||||||
attrs = [{<<"type">>, <<"headline">>}],
|
|
||||||
children = SubjectEls ++ BodyEls
|
|
||||||
},
|
|
||||||
Sessions = ejabberd_sm:dirty_get_sessions_list(),
|
Sessions = ejabberd_sm:dirty_get_sessions_list(),
|
||||||
Local = jid:make(<<>>, Host, <<>>),
|
Local = jid:make(Host),
|
||||||
lists:foreach(
|
lists:foreach(
|
||||||
fun({U, S, R}) ->
|
fun({U, S, R}) ->
|
||||||
Dest = jid:make(U, S, R),
|
Dest = jid:make(U, S, R),
|
||||||
|
@ -15,6 +15,30 @@ decode(_el) -> decode(_el, []).
|
|||||||
decode({xmlel, _name, _attrs, _} = _el, Opts) ->
|
decode({xmlel, _name, _attrs, _} = _el, Opts) ->
|
||||||
IgnoreEls = proplists:get_bool(ignore_els, Opts),
|
IgnoreEls = proplists:get_bool(ignore_els, Opts),
|
||||||
case {_name, get_attr(<<"xmlns">>, _attrs)} of
|
case {_name, get_attr(<<"xmlns">>, _attrs)} of
|
||||||
|
{<<"command">>,
|
||||||
|
<<"http://jabber.org/protocol/commands">>} ->
|
||||||
|
decode_adhoc_command(<<"http://jabber.org/protocol/commands">>,
|
||||||
|
IgnoreEls, _el);
|
||||||
|
{<<"note">>,
|
||||||
|
<<"http://jabber.org/protocol/commands">>} ->
|
||||||
|
decode_adhoc_command_notes(<<"http://jabber.org/protocol/commands">>,
|
||||||
|
IgnoreEls, _el);
|
||||||
|
{<<"actions">>,
|
||||||
|
<<"http://jabber.org/protocol/commands">>} ->
|
||||||
|
decode_adhoc_command_actions(<<"http://jabber.org/protocol/commands">>,
|
||||||
|
IgnoreEls, _el);
|
||||||
|
{<<"complete">>,
|
||||||
|
<<"http://jabber.org/protocol/commands">>} ->
|
||||||
|
decode_adhoc_command_complete(<<"http://jabber.org/protocol/commands">>,
|
||||||
|
IgnoreEls, _el);
|
||||||
|
{<<"next">>,
|
||||||
|
<<"http://jabber.org/protocol/commands">>} ->
|
||||||
|
decode_adhoc_command_next(<<"http://jabber.org/protocol/commands">>,
|
||||||
|
IgnoreEls, _el);
|
||||||
|
{<<"prev">>,
|
||||||
|
<<"http://jabber.org/protocol/commands">>} ->
|
||||||
|
decode_adhoc_command_prev(<<"http://jabber.org/protocol/commands">>,
|
||||||
|
IgnoreEls, _el);
|
||||||
{<<"client-id">>, <<"urn:xmpp:sid:0">>} ->
|
{<<"client-id">>, <<"urn:xmpp:sid:0">>} ->
|
||||||
decode_client_id(<<"urn:xmpp:sid:0">>, IgnoreEls, _el);
|
decode_client_id(<<"urn:xmpp:sid:0">>, IgnoreEls, _el);
|
||||||
{<<"stanza-id">>, <<"urn:xmpp:sid:0">>} ->
|
{<<"stanza-id">>, <<"urn:xmpp:sid:0">>} ->
|
||||||
@ -1254,6 +1278,24 @@ decode({xmlel, _name, _attrs, _} = _el, Opts) ->
|
|||||||
|
|
||||||
is_known_tag({xmlel, _name, _attrs, _} = _el) ->
|
is_known_tag({xmlel, _name, _attrs, _} = _el) ->
|
||||||
case {_name, get_attr(<<"xmlns">>, _attrs)} of
|
case {_name, get_attr(<<"xmlns">>, _attrs)} of
|
||||||
|
{<<"command">>,
|
||||||
|
<<"http://jabber.org/protocol/commands">>} ->
|
||||||
|
true;
|
||||||
|
{<<"note">>,
|
||||||
|
<<"http://jabber.org/protocol/commands">>} ->
|
||||||
|
true;
|
||||||
|
{<<"actions">>,
|
||||||
|
<<"http://jabber.org/protocol/commands">>} ->
|
||||||
|
true;
|
||||||
|
{<<"complete">>,
|
||||||
|
<<"http://jabber.org/protocol/commands">>} ->
|
||||||
|
true;
|
||||||
|
{<<"next">>,
|
||||||
|
<<"http://jabber.org/protocol/commands">>} ->
|
||||||
|
true;
|
||||||
|
{<<"prev">>,
|
||||||
|
<<"http://jabber.org/protocol/commands">>} ->
|
||||||
|
true;
|
||||||
{<<"client-id">>, <<"urn:xmpp:sid:0">>} -> true;
|
{<<"client-id">>, <<"urn:xmpp:sid:0">>} -> true;
|
||||||
{<<"stanza-id">>, <<"urn:xmpp:sid:0">>} -> true;
|
{<<"stanza-id">>, <<"urn:xmpp:sid:0">>} -> true;
|
||||||
{<<"addresses">>,
|
{<<"addresses">>,
|
||||||
@ -2483,7 +2525,20 @@ encode({stanza_id, _, _} = Stanza_id) ->
|
|||||||
[{<<"xmlns">>, <<"urn:xmpp:sid:0">>}]);
|
[{<<"xmlns">>, <<"urn:xmpp:sid:0">>}]);
|
||||||
encode({client_id, _} = Client_id) ->
|
encode({client_id, _} = Client_id) ->
|
||||||
encode_client_id(Client_id,
|
encode_client_id(Client_id,
|
||||||
[{<<"xmlns">>, <<"urn:xmpp:sid:0">>}]).
|
[{<<"xmlns">>, <<"urn:xmpp:sid:0">>}]);
|
||||||
|
encode({adhoc_actions, _, _, _, _} = Actions) ->
|
||||||
|
encode_adhoc_command_actions(Actions,
|
||||||
|
[{<<"xmlns">>,
|
||||||
|
<<"http://jabber.org/protocol/commands">>}]);
|
||||||
|
encode({adhoc_note, _, _} = Note) ->
|
||||||
|
encode_adhoc_command_notes(Note,
|
||||||
|
[{<<"xmlns">>,
|
||||||
|
<<"http://jabber.org/protocol/commands">>}]);
|
||||||
|
encode({adhoc_command, _, _, _, _, _, _, _, _} =
|
||||||
|
Command) ->
|
||||||
|
encode_adhoc_command(Command,
|
||||||
|
[{<<"xmlns">>,
|
||||||
|
<<"http://jabber.org/protocol/commands">>}]).
|
||||||
|
|
||||||
get_name({last, _, _}) -> <<"query">>;
|
get_name({last, _, _}) -> <<"query">>;
|
||||||
get_name({version, _, _, _}) -> <<"query">>;
|
get_name({version, _, _, _}) -> <<"query">>;
|
||||||
@ -2661,7 +2716,11 @@ get_name({nick, _}) -> <<"nick">>;
|
|||||||
get_name({address, _, _, _, _, _}) -> <<"address">>;
|
get_name({address, _, _, _, _, _}) -> <<"address">>;
|
||||||
get_name({addresses, _}) -> <<"addresses">>;
|
get_name({addresses, _}) -> <<"addresses">>;
|
||||||
get_name({stanza_id, _, _}) -> <<"stanza-id">>;
|
get_name({stanza_id, _, _}) -> <<"stanza-id">>;
|
||||||
get_name({client_id, _}) -> <<"client-id">>.
|
get_name({client_id, _}) -> <<"client-id">>;
|
||||||
|
get_name({adhoc_actions, _, _, _, _}) -> <<"actions">>;
|
||||||
|
get_name({adhoc_note, _, _}) -> <<"note">>;
|
||||||
|
get_name({adhoc_command, _, _, _, _, _, _, _, _}) ->
|
||||||
|
<<"command">>.
|
||||||
|
|
||||||
get_ns({last, _, _}) -> <<"jabber:iq:last">>;
|
get_ns({last, _, _}) -> <<"jabber:iq:last">>;
|
||||||
get_ns({version, _, _, _}) -> <<"jabber:iq:version">>;
|
get_ns({version, _, _, _}) -> <<"jabber:iq:version">>;
|
||||||
@ -2909,7 +2968,13 @@ get_ns({address, _, _, _, _, _}) ->
|
|||||||
get_ns({addresses, _}) ->
|
get_ns({addresses, _}) ->
|
||||||
<<"http://jabber.org/protocol/address">>;
|
<<"http://jabber.org/protocol/address">>;
|
||||||
get_ns({stanza_id, _, _}) -> <<"urn:xmpp:sid:0">>;
|
get_ns({stanza_id, _, _}) -> <<"urn:xmpp:sid:0">>;
|
||||||
get_ns({client_id, _}) -> <<"urn:xmpp:sid:0">>.
|
get_ns({client_id, _}) -> <<"urn:xmpp:sid:0">>;
|
||||||
|
get_ns({adhoc_actions, _, _, _, _}) ->
|
||||||
|
<<"http://jabber.org/protocol/commands">>;
|
||||||
|
get_ns({adhoc_note, _, _}) ->
|
||||||
|
<<"http://jabber.org/protocol/commands">>;
|
||||||
|
get_ns({adhoc_command, _, _, _, _, _, _, _, _}) ->
|
||||||
|
<<"http://jabber.org/protocol/commands">>.
|
||||||
|
|
||||||
dec_int(Val) -> dec_int(Val, infinity, infinity).
|
dec_int(Val) -> dec_int(Val, infinity, infinity).
|
||||||
|
|
||||||
@ -3140,6 +3205,11 @@ pp(address, 5) -> [type, jid, desc, node, delivered];
|
|||||||
pp(addresses, 1) -> [list];
|
pp(addresses, 1) -> [list];
|
||||||
pp(stanza_id, 2) -> [by, id];
|
pp(stanza_id, 2) -> [by, id];
|
||||||
pp(client_id, 1) -> [id];
|
pp(client_id, 1) -> [id];
|
||||||
|
pp(adhoc_actions, 4) -> [execute, prev, next, complete];
|
||||||
|
pp(adhoc_note, 2) -> [type, data];
|
||||||
|
pp(adhoc_command, 8) ->
|
||||||
|
[node, action, sid, status, lang, actions, notes,
|
||||||
|
xdata];
|
||||||
pp(_, _) -> no.
|
pp(_, _) -> no.
|
||||||
|
|
||||||
join([], _Sep) -> <<>>;
|
join([], _Sep) -> <<>>;
|
||||||
@ -3186,6 +3256,474 @@ dec_tzo(Val) ->
|
|||||||
M = jlib:binary_to_integer(M1),
|
M = jlib:binary_to_integer(M1),
|
||||||
if H >= -12, H =< 12, M >= 0, M < 60 -> {H, M} end.
|
if H >= -12, H =< 12, M >= 0, M < 60 -> {H, M} end.
|
||||||
|
|
||||||
|
decode_adhoc_command(__TopXMLNS, __IgnoreEls,
|
||||||
|
{xmlel, <<"command">>, _attrs, _els}) ->
|
||||||
|
{Xdata, Notes, Actions} =
|
||||||
|
decode_adhoc_command_els(__TopXMLNS, __IgnoreEls, _els,
|
||||||
|
undefined, [], undefined),
|
||||||
|
{Node, Lang, Sid, Status, Action} =
|
||||||
|
decode_adhoc_command_attrs(__TopXMLNS, _attrs,
|
||||||
|
undefined, undefined, undefined, undefined,
|
||||||
|
undefined),
|
||||||
|
{adhoc_command, Node, Action, Sid, Status, Lang,
|
||||||
|
Actions, Notes, Xdata}.
|
||||||
|
|
||||||
|
decode_adhoc_command_els(__TopXMLNS, __IgnoreEls, [],
|
||||||
|
Xdata, Notes, Actions) ->
|
||||||
|
{Xdata, lists:reverse(Notes), Actions};
|
||||||
|
decode_adhoc_command_els(__TopXMLNS, __IgnoreEls,
|
||||||
|
[{xmlel, <<"actions">>, _attrs, _} = _el | _els],
|
||||||
|
Xdata, Notes, Actions) ->
|
||||||
|
case get_attr(<<"xmlns">>, _attrs) of
|
||||||
|
<<"">>
|
||||||
|
when __TopXMLNS ==
|
||||||
|
<<"http://jabber.org/protocol/commands">> ->
|
||||||
|
decode_adhoc_command_els(__TopXMLNS, __IgnoreEls, _els,
|
||||||
|
Xdata, Notes,
|
||||||
|
decode_adhoc_command_actions(__TopXMLNS,
|
||||||
|
__IgnoreEls,
|
||||||
|
_el));
|
||||||
|
<<"http://jabber.org/protocol/commands">> ->
|
||||||
|
decode_adhoc_command_els(__TopXMLNS, __IgnoreEls, _els,
|
||||||
|
Xdata, Notes,
|
||||||
|
decode_adhoc_command_actions(<<"http://jabber.org/protocol/commands">>,
|
||||||
|
__IgnoreEls,
|
||||||
|
_el));
|
||||||
|
_ ->
|
||||||
|
decode_adhoc_command_els(__TopXMLNS, __IgnoreEls, _els,
|
||||||
|
Xdata, Notes, Actions)
|
||||||
|
end;
|
||||||
|
decode_adhoc_command_els(__TopXMLNS, __IgnoreEls,
|
||||||
|
[{xmlel, <<"x">>, _attrs, _} = _el | _els], Xdata,
|
||||||
|
Notes, Actions) ->
|
||||||
|
case get_attr(<<"xmlns">>, _attrs) of
|
||||||
|
<<"jabber:x:data">> ->
|
||||||
|
decode_adhoc_command_els(__TopXMLNS, __IgnoreEls, _els,
|
||||||
|
decode_xdata(<<"jabber:x:data">>,
|
||||||
|
__IgnoreEls, _el),
|
||||||
|
Notes, Actions);
|
||||||
|
_ ->
|
||||||
|
decode_adhoc_command_els(__TopXMLNS, __IgnoreEls, _els,
|
||||||
|
Xdata, Notes, Actions)
|
||||||
|
end;
|
||||||
|
decode_adhoc_command_els(__TopXMLNS, __IgnoreEls,
|
||||||
|
[{xmlel, <<"note">>, _attrs, _} = _el | _els], Xdata,
|
||||||
|
Notes, Actions) ->
|
||||||
|
case get_attr(<<"xmlns">>, _attrs) of
|
||||||
|
<<"">>
|
||||||
|
when __TopXMLNS ==
|
||||||
|
<<"http://jabber.org/protocol/commands">> ->
|
||||||
|
decode_adhoc_command_els(__TopXMLNS, __IgnoreEls, _els,
|
||||||
|
Xdata,
|
||||||
|
[decode_adhoc_command_notes(__TopXMLNS,
|
||||||
|
__IgnoreEls, _el)
|
||||||
|
| Notes],
|
||||||
|
Actions);
|
||||||
|
<<"http://jabber.org/protocol/commands">> ->
|
||||||
|
decode_adhoc_command_els(__TopXMLNS, __IgnoreEls, _els,
|
||||||
|
Xdata,
|
||||||
|
[decode_adhoc_command_notes(<<"http://jabber.org/protocol/commands">>,
|
||||||
|
__IgnoreEls, _el)
|
||||||
|
| Notes],
|
||||||
|
Actions);
|
||||||
|
_ ->
|
||||||
|
decode_adhoc_command_els(__TopXMLNS, __IgnoreEls, _els,
|
||||||
|
Xdata, Notes, Actions)
|
||||||
|
end;
|
||||||
|
decode_adhoc_command_els(__TopXMLNS, __IgnoreEls,
|
||||||
|
[_ | _els], Xdata, Notes, Actions) ->
|
||||||
|
decode_adhoc_command_els(__TopXMLNS, __IgnoreEls, _els,
|
||||||
|
Xdata, Notes, Actions).
|
||||||
|
|
||||||
|
decode_adhoc_command_attrs(__TopXMLNS,
|
||||||
|
[{<<"node">>, _val} | _attrs], _Node, Lang, Sid,
|
||||||
|
Status, Action) ->
|
||||||
|
decode_adhoc_command_attrs(__TopXMLNS, _attrs, _val,
|
||||||
|
Lang, Sid, Status, Action);
|
||||||
|
decode_adhoc_command_attrs(__TopXMLNS,
|
||||||
|
[{<<"xml:lang">>, _val} | _attrs], Node, _Lang, Sid,
|
||||||
|
Status, Action) ->
|
||||||
|
decode_adhoc_command_attrs(__TopXMLNS, _attrs, Node,
|
||||||
|
_val, Sid, Status, Action);
|
||||||
|
decode_adhoc_command_attrs(__TopXMLNS,
|
||||||
|
[{<<"sessionid">>, _val} | _attrs], Node, Lang, _Sid,
|
||||||
|
Status, Action) ->
|
||||||
|
decode_adhoc_command_attrs(__TopXMLNS, _attrs, Node,
|
||||||
|
Lang, _val, Status, Action);
|
||||||
|
decode_adhoc_command_attrs(__TopXMLNS,
|
||||||
|
[{<<"status">>, _val} | _attrs], Node, Lang, Sid,
|
||||||
|
_Status, Action) ->
|
||||||
|
decode_adhoc_command_attrs(__TopXMLNS, _attrs, Node,
|
||||||
|
Lang, Sid, _val, Action);
|
||||||
|
decode_adhoc_command_attrs(__TopXMLNS,
|
||||||
|
[{<<"action">>, _val} | _attrs], Node, Lang, Sid,
|
||||||
|
Status, _Action) ->
|
||||||
|
decode_adhoc_command_attrs(__TopXMLNS, _attrs, Node,
|
||||||
|
Lang, Sid, Status, _val);
|
||||||
|
decode_adhoc_command_attrs(__TopXMLNS, [_ | _attrs],
|
||||||
|
Node, Lang, Sid, Status, Action) ->
|
||||||
|
decode_adhoc_command_attrs(__TopXMLNS, _attrs, Node,
|
||||||
|
Lang, Sid, Status, Action);
|
||||||
|
decode_adhoc_command_attrs(__TopXMLNS, [], Node, Lang,
|
||||||
|
Sid, Status, Action) ->
|
||||||
|
{decode_adhoc_command_attr_node(__TopXMLNS, Node),
|
||||||
|
'decode_adhoc_command_attr_xml:lang'(__TopXMLNS, Lang),
|
||||||
|
decode_adhoc_command_attr_sessionid(__TopXMLNS, Sid),
|
||||||
|
decode_adhoc_command_attr_status(__TopXMLNS, Status),
|
||||||
|
decode_adhoc_command_attr_action(__TopXMLNS, Action)}.
|
||||||
|
|
||||||
|
encode_adhoc_command({adhoc_command, Node, Action, Sid,
|
||||||
|
Status, Lang, Actions, Notes, Xdata},
|
||||||
|
_xmlns_attrs) ->
|
||||||
|
_els =
|
||||||
|
lists:reverse('encode_adhoc_command_$xdata'(Xdata,
|
||||||
|
'encode_adhoc_command_$notes'(Notes,
|
||||||
|
'encode_adhoc_command_$actions'(Actions,
|
||||||
|
[])))),
|
||||||
|
_attrs = encode_adhoc_command_attr_action(Action,
|
||||||
|
encode_adhoc_command_attr_status(Status,
|
||||||
|
encode_adhoc_command_attr_sessionid(Sid,
|
||||||
|
'encode_adhoc_command_attr_xml:lang'(Lang,
|
||||||
|
encode_adhoc_command_attr_node(Node,
|
||||||
|
_xmlns_attrs))))),
|
||||||
|
{xmlel, <<"command">>, _attrs, _els}.
|
||||||
|
|
||||||
|
'encode_adhoc_command_$xdata'(undefined, _acc) -> _acc;
|
||||||
|
'encode_adhoc_command_$xdata'(Xdata, _acc) ->
|
||||||
|
[encode_xdata(Xdata,
|
||||||
|
[{<<"xmlns">>, <<"jabber:x:data">>}])
|
||||||
|
| _acc].
|
||||||
|
|
||||||
|
'encode_adhoc_command_$notes'([], _acc) -> _acc;
|
||||||
|
'encode_adhoc_command_$notes'([Notes | _els], _acc) ->
|
||||||
|
'encode_adhoc_command_$notes'(_els,
|
||||||
|
[encode_adhoc_command_notes(Notes, [])
|
||||||
|
| _acc]).
|
||||||
|
|
||||||
|
'encode_adhoc_command_$actions'(undefined, _acc) ->
|
||||||
|
_acc;
|
||||||
|
'encode_adhoc_command_$actions'(Actions, _acc) ->
|
||||||
|
[encode_adhoc_command_actions(Actions, []) | _acc].
|
||||||
|
|
||||||
|
decode_adhoc_command_attr_node(__TopXMLNS, undefined) ->
|
||||||
|
erlang:error({xmpp_codec,
|
||||||
|
{missing_attr, <<"node">>, <<"command">>, __TopXMLNS}});
|
||||||
|
decode_adhoc_command_attr_node(__TopXMLNS, _val) ->
|
||||||
|
_val.
|
||||||
|
|
||||||
|
encode_adhoc_command_attr_node(_val, _acc) ->
|
||||||
|
[{<<"node">>, _val} | _acc].
|
||||||
|
|
||||||
|
'decode_adhoc_command_attr_xml:lang'(__TopXMLNS,
|
||||||
|
undefined) ->
|
||||||
|
undefined;
|
||||||
|
'decode_adhoc_command_attr_xml:lang'(__TopXMLNS,
|
||||||
|
_val) ->
|
||||||
|
_val.
|
||||||
|
|
||||||
|
'encode_adhoc_command_attr_xml:lang'(undefined, _acc) ->
|
||||||
|
_acc;
|
||||||
|
'encode_adhoc_command_attr_xml:lang'(_val, _acc) ->
|
||||||
|
[{<<"xml:lang">>, _val} | _acc].
|
||||||
|
|
||||||
|
decode_adhoc_command_attr_sessionid(__TopXMLNS,
|
||||||
|
undefined) ->
|
||||||
|
undefined;
|
||||||
|
decode_adhoc_command_attr_sessionid(__TopXMLNS, _val) ->
|
||||||
|
_val.
|
||||||
|
|
||||||
|
encode_adhoc_command_attr_sessionid(undefined, _acc) ->
|
||||||
|
_acc;
|
||||||
|
encode_adhoc_command_attr_sessionid(_val, _acc) ->
|
||||||
|
[{<<"sessionid">>, _val} | _acc].
|
||||||
|
|
||||||
|
decode_adhoc_command_attr_status(__TopXMLNS,
|
||||||
|
undefined) ->
|
||||||
|
undefined;
|
||||||
|
decode_adhoc_command_attr_status(__TopXMLNS, _val) ->
|
||||||
|
case catch dec_enum(_val,
|
||||||
|
[canceled, completed, executing])
|
||||||
|
of
|
||||||
|
{'EXIT', _} ->
|
||||||
|
erlang:error({xmpp_codec,
|
||||||
|
{bad_attr_value, <<"status">>, <<"command">>,
|
||||||
|
__TopXMLNS}});
|
||||||
|
_res -> _res
|
||||||
|
end.
|
||||||
|
|
||||||
|
encode_adhoc_command_attr_status(undefined, _acc) ->
|
||||||
|
_acc;
|
||||||
|
encode_adhoc_command_attr_status(_val, _acc) ->
|
||||||
|
[{<<"status">>, enc_enum(_val)} | _acc].
|
||||||
|
|
||||||
|
decode_adhoc_command_attr_action(__TopXMLNS,
|
||||||
|
undefined) ->
|
||||||
|
execute;
|
||||||
|
decode_adhoc_command_attr_action(__TopXMLNS, _val) ->
|
||||||
|
case catch dec_enum(_val,
|
||||||
|
[cancel, complete, execute, next, prev])
|
||||||
|
of
|
||||||
|
{'EXIT', _} ->
|
||||||
|
erlang:error({xmpp_codec,
|
||||||
|
{bad_attr_value, <<"action">>, <<"command">>,
|
||||||
|
__TopXMLNS}});
|
||||||
|
_res -> _res
|
||||||
|
end.
|
||||||
|
|
||||||
|
encode_adhoc_command_attr_action(execute, _acc) -> _acc;
|
||||||
|
encode_adhoc_command_attr_action(_val, _acc) ->
|
||||||
|
[{<<"action">>, enc_enum(_val)} | _acc].
|
||||||
|
|
||||||
|
decode_adhoc_command_notes(__TopXMLNS, __IgnoreEls,
|
||||||
|
{xmlel, <<"note">>, _attrs, _els}) ->
|
||||||
|
Data = decode_adhoc_command_notes_els(__TopXMLNS,
|
||||||
|
__IgnoreEls, _els, <<>>),
|
||||||
|
Type = decode_adhoc_command_notes_attrs(__TopXMLNS,
|
||||||
|
_attrs, undefined),
|
||||||
|
{adhoc_note, Type, Data}.
|
||||||
|
|
||||||
|
decode_adhoc_command_notes_els(__TopXMLNS, __IgnoreEls,
|
||||||
|
[], Data) ->
|
||||||
|
decode_adhoc_command_notes_cdata(__TopXMLNS, Data);
|
||||||
|
decode_adhoc_command_notes_els(__TopXMLNS, __IgnoreEls,
|
||||||
|
[{xmlcdata, _data} | _els], Data) ->
|
||||||
|
decode_adhoc_command_notes_els(__TopXMLNS, __IgnoreEls,
|
||||||
|
_els, <<Data/binary, _data/binary>>);
|
||||||
|
decode_adhoc_command_notes_els(__TopXMLNS, __IgnoreEls,
|
||||||
|
[_ | _els], Data) ->
|
||||||
|
decode_adhoc_command_notes_els(__TopXMLNS, __IgnoreEls,
|
||||||
|
_els, Data).
|
||||||
|
|
||||||
|
decode_adhoc_command_notes_attrs(__TopXMLNS,
|
||||||
|
[{<<"type">>, _val} | _attrs], _Type) ->
|
||||||
|
decode_adhoc_command_notes_attrs(__TopXMLNS, _attrs,
|
||||||
|
_val);
|
||||||
|
decode_adhoc_command_notes_attrs(__TopXMLNS,
|
||||||
|
[_ | _attrs], Type) ->
|
||||||
|
decode_adhoc_command_notes_attrs(__TopXMLNS, _attrs,
|
||||||
|
Type);
|
||||||
|
decode_adhoc_command_notes_attrs(__TopXMLNS, [],
|
||||||
|
Type) ->
|
||||||
|
decode_adhoc_command_notes_attr_type(__TopXMLNS, Type).
|
||||||
|
|
||||||
|
encode_adhoc_command_notes({adhoc_note, Type, Data},
|
||||||
|
_xmlns_attrs) ->
|
||||||
|
_els = encode_adhoc_command_notes_cdata(Data, []),
|
||||||
|
_attrs = encode_adhoc_command_notes_attr_type(Type,
|
||||||
|
_xmlns_attrs),
|
||||||
|
{xmlel, <<"note">>, _attrs, _els}.
|
||||||
|
|
||||||
|
decode_adhoc_command_notes_attr_type(__TopXMLNS,
|
||||||
|
undefined) ->
|
||||||
|
info;
|
||||||
|
decode_adhoc_command_notes_attr_type(__TopXMLNS,
|
||||||
|
_val) ->
|
||||||
|
case catch dec_enum(_val, [info, warn, error]) of
|
||||||
|
{'EXIT', _} ->
|
||||||
|
erlang:error({xmpp_codec,
|
||||||
|
{bad_attr_value, <<"type">>, <<"note">>, __TopXMLNS}});
|
||||||
|
_res -> _res
|
||||||
|
end.
|
||||||
|
|
||||||
|
encode_adhoc_command_notes_attr_type(info, _acc) ->
|
||||||
|
_acc;
|
||||||
|
encode_adhoc_command_notes_attr_type(_val, _acc) ->
|
||||||
|
[{<<"type">>, enc_enum(_val)} | _acc].
|
||||||
|
|
||||||
|
decode_adhoc_command_notes_cdata(__TopXMLNS, <<>>) ->
|
||||||
|
<<>>;
|
||||||
|
decode_adhoc_command_notes_cdata(__TopXMLNS, _val) ->
|
||||||
|
_val.
|
||||||
|
|
||||||
|
encode_adhoc_command_notes_cdata(<<>>, _acc) -> _acc;
|
||||||
|
encode_adhoc_command_notes_cdata(_val, _acc) ->
|
||||||
|
[{xmlcdata, _val} | _acc].
|
||||||
|
|
||||||
|
decode_adhoc_command_actions(__TopXMLNS, __IgnoreEls,
|
||||||
|
{xmlel, <<"actions">>, _attrs, _els}) ->
|
||||||
|
{Next, Complete, Prev} =
|
||||||
|
decode_adhoc_command_actions_els(__TopXMLNS,
|
||||||
|
__IgnoreEls, _els, false, false,
|
||||||
|
false),
|
||||||
|
Execute = decode_adhoc_command_actions_attrs(__TopXMLNS,
|
||||||
|
_attrs, undefined),
|
||||||
|
{adhoc_actions, Execute, Prev, Next, Complete}.
|
||||||
|
|
||||||
|
decode_adhoc_command_actions_els(__TopXMLNS,
|
||||||
|
__IgnoreEls, [], Next, Complete, Prev) ->
|
||||||
|
{Next, Complete, Prev};
|
||||||
|
decode_adhoc_command_actions_els(__TopXMLNS,
|
||||||
|
__IgnoreEls,
|
||||||
|
[{xmlel, <<"prev">>, _attrs, _} = _el | _els],
|
||||||
|
Next, Complete, Prev) ->
|
||||||
|
case get_attr(<<"xmlns">>, _attrs) of
|
||||||
|
<<"">>
|
||||||
|
when __TopXMLNS ==
|
||||||
|
<<"http://jabber.org/protocol/commands">> ->
|
||||||
|
decode_adhoc_command_actions_els(__TopXMLNS,
|
||||||
|
__IgnoreEls, _els, Next, Complete,
|
||||||
|
decode_adhoc_command_prev(__TopXMLNS,
|
||||||
|
__IgnoreEls,
|
||||||
|
_el));
|
||||||
|
<<"http://jabber.org/protocol/commands">> ->
|
||||||
|
decode_adhoc_command_actions_els(__TopXMLNS,
|
||||||
|
__IgnoreEls, _els, Next, Complete,
|
||||||
|
decode_adhoc_command_prev(<<"http://jabber.org/protocol/commands">>,
|
||||||
|
__IgnoreEls,
|
||||||
|
_el));
|
||||||
|
_ ->
|
||||||
|
decode_adhoc_command_actions_els(__TopXMLNS,
|
||||||
|
__IgnoreEls, _els, Next, Complete,
|
||||||
|
Prev)
|
||||||
|
end;
|
||||||
|
decode_adhoc_command_actions_els(__TopXMLNS,
|
||||||
|
__IgnoreEls,
|
||||||
|
[{xmlel, <<"next">>, _attrs, _} = _el | _els],
|
||||||
|
Next, Complete, Prev) ->
|
||||||
|
case get_attr(<<"xmlns">>, _attrs) of
|
||||||
|
<<"">>
|
||||||
|
when __TopXMLNS ==
|
||||||
|
<<"http://jabber.org/protocol/commands">> ->
|
||||||
|
decode_adhoc_command_actions_els(__TopXMLNS,
|
||||||
|
__IgnoreEls, _els,
|
||||||
|
decode_adhoc_command_next(__TopXMLNS,
|
||||||
|
__IgnoreEls,
|
||||||
|
_el),
|
||||||
|
Complete, Prev);
|
||||||
|
<<"http://jabber.org/protocol/commands">> ->
|
||||||
|
decode_adhoc_command_actions_els(__TopXMLNS,
|
||||||
|
__IgnoreEls, _els,
|
||||||
|
decode_adhoc_command_next(<<"http://jabber.org/protocol/commands">>,
|
||||||
|
__IgnoreEls,
|
||||||
|
_el),
|
||||||
|
Complete, Prev);
|
||||||
|
_ ->
|
||||||
|
decode_adhoc_command_actions_els(__TopXMLNS,
|
||||||
|
__IgnoreEls, _els, Next, Complete,
|
||||||
|
Prev)
|
||||||
|
end;
|
||||||
|
decode_adhoc_command_actions_els(__TopXMLNS,
|
||||||
|
__IgnoreEls,
|
||||||
|
[{xmlel, <<"complete">>, _attrs, _} = _el
|
||||||
|
| _els],
|
||||||
|
Next, Complete, Prev) ->
|
||||||
|
case get_attr(<<"xmlns">>, _attrs) of
|
||||||
|
<<"">>
|
||||||
|
when __TopXMLNS ==
|
||||||
|
<<"http://jabber.org/protocol/commands">> ->
|
||||||
|
decode_adhoc_command_actions_els(__TopXMLNS,
|
||||||
|
__IgnoreEls, _els, Next,
|
||||||
|
decode_adhoc_command_complete(__TopXMLNS,
|
||||||
|
__IgnoreEls,
|
||||||
|
_el),
|
||||||
|
Prev);
|
||||||
|
<<"http://jabber.org/protocol/commands">> ->
|
||||||
|
decode_adhoc_command_actions_els(__TopXMLNS,
|
||||||
|
__IgnoreEls, _els, Next,
|
||||||
|
decode_adhoc_command_complete(<<"http://jabber.org/protocol/commands">>,
|
||||||
|
__IgnoreEls,
|
||||||
|
_el),
|
||||||
|
Prev);
|
||||||
|
_ ->
|
||||||
|
decode_adhoc_command_actions_els(__TopXMLNS,
|
||||||
|
__IgnoreEls, _els, Next, Complete,
|
||||||
|
Prev)
|
||||||
|
end;
|
||||||
|
decode_adhoc_command_actions_els(__TopXMLNS,
|
||||||
|
__IgnoreEls, [_ | _els], Next, Complete,
|
||||||
|
Prev) ->
|
||||||
|
decode_adhoc_command_actions_els(__TopXMLNS,
|
||||||
|
__IgnoreEls, _els, Next, Complete, Prev).
|
||||||
|
|
||||||
|
decode_adhoc_command_actions_attrs(__TopXMLNS,
|
||||||
|
[{<<"execute">>, _val} | _attrs],
|
||||||
|
_Execute) ->
|
||||||
|
decode_adhoc_command_actions_attrs(__TopXMLNS, _attrs,
|
||||||
|
_val);
|
||||||
|
decode_adhoc_command_actions_attrs(__TopXMLNS,
|
||||||
|
[_ | _attrs], Execute) ->
|
||||||
|
decode_adhoc_command_actions_attrs(__TopXMLNS, _attrs,
|
||||||
|
Execute);
|
||||||
|
decode_adhoc_command_actions_attrs(__TopXMLNS, [],
|
||||||
|
Execute) ->
|
||||||
|
decode_adhoc_command_actions_attr_execute(__TopXMLNS,
|
||||||
|
Execute).
|
||||||
|
|
||||||
|
encode_adhoc_command_actions({adhoc_actions, Execute,
|
||||||
|
Prev, Next, Complete},
|
||||||
|
_xmlns_attrs) ->
|
||||||
|
_els =
|
||||||
|
lists:reverse('encode_adhoc_command_actions_$next'(Next,
|
||||||
|
'encode_adhoc_command_actions_$complete'(Complete,
|
||||||
|
'encode_adhoc_command_actions_$prev'(Prev,
|
||||||
|
[])))),
|
||||||
|
_attrs =
|
||||||
|
encode_adhoc_command_actions_attr_execute(Execute,
|
||||||
|
_xmlns_attrs),
|
||||||
|
{xmlel, <<"actions">>, _attrs, _els}.
|
||||||
|
|
||||||
|
'encode_adhoc_command_actions_$next'(false, _acc) ->
|
||||||
|
_acc;
|
||||||
|
'encode_adhoc_command_actions_$next'(Next, _acc) ->
|
||||||
|
[encode_adhoc_command_next(Next, []) | _acc].
|
||||||
|
|
||||||
|
'encode_adhoc_command_actions_$complete'(false, _acc) ->
|
||||||
|
_acc;
|
||||||
|
'encode_adhoc_command_actions_$complete'(Complete,
|
||||||
|
_acc) ->
|
||||||
|
[encode_adhoc_command_complete(Complete, []) | _acc].
|
||||||
|
|
||||||
|
'encode_adhoc_command_actions_$prev'(false, _acc) ->
|
||||||
|
_acc;
|
||||||
|
'encode_adhoc_command_actions_$prev'(Prev, _acc) ->
|
||||||
|
[encode_adhoc_command_prev(Prev, []) | _acc].
|
||||||
|
|
||||||
|
decode_adhoc_command_actions_attr_execute(__TopXMLNS,
|
||||||
|
undefined) ->
|
||||||
|
undefined;
|
||||||
|
decode_adhoc_command_actions_attr_execute(__TopXMLNS,
|
||||||
|
_val) ->
|
||||||
|
case catch dec_enum(_val, [complete, next, prev]) of
|
||||||
|
{'EXIT', _} ->
|
||||||
|
erlang:error({xmpp_codec,
|
||||||
|
{bad_attr_value, <<"execute">>, <<"actions">>,
|
||||||
|
__TopXMLNS}});
|
||||||
|
_res -> _res
|
||||||
|
end.
|
||||||
|
|
||||||
|
encode_adhoc_command_actions_attr_execute(undefined,
|
||||||
|
_acc) ->
|
||||||
|
_acc;
|
||||||
|
encode_adhoc_command_actions_attr_execute(_val, _acc) ->
|
||||||
|
[{<<"execute">>, enc_enum(_val)} | _acc].
|
||||||
|
|
||||||
|
decode_adhoc_command_complete(__TopXMLNS, __IgnoreEls,
|
||||||
|
{xmlel, <<"complete">>, _attrs, _els}) ->
|
||||||
|
true.
|
||||||
|
|
||||||
|
encode_adhoc_command_complete(true, _xmlns_attrs) ->
|
||||||
|
_els = [],
|
||||||
|
_attrs = _xmlns_attrs,
|
||||||
|
{xmlel, <<"complete">>, _attrs, _els}.
|
||||||
|
|
||||||
|
decode_adhoc_command_next(__TopXMLNS, __IgnoreEls,
|
||||||
|
{xmlel, <<"next">>, _attrs, _els}) ->
|
||||||
|
true.
|
||||||
|
|
||||||
|
encode_adhoc_command_next(true, _xmlns_attrs) ->
|
||||||
|
_els = [],
|
||||||
|
_attrs = _xmlns_attrs,
|
||||||
|
{xmlel, <<"next">>, _attrs, _els}.
|
||||||
|
|
||||||
|
decode_adhoc_command_prev(__TopXMLNS, __IgnoreEls,
|
||||||
|
{xmlel, <<"prev">>, _attrs, _els}) ->
|
||||||
|
true.
|
||||||
|
|
||||||
|
encode_adhoc_command_prev(true, _xmlns_attrs) ->
|
||||||
|
_els = [],
|
||||||
|
_attrs = _xmlns_attrs,
|
||||||
|
{xmlel, <<"prev">>, _attrs, _els}.
|
||||||
|
|
||||||
decode_client_id(__TopXMLNS, __IgnoreEls,
|
decode_client_id(__TopXMLNS, __IgnoreEls,
|
||||||
{xmlel, <<"client-id">>, _attrs, _els}) ->
|
{xmlel, <<"client-id">>, _attrs, _els}) ->
|
||||||
Id = decode_client_id_attrs(__TopXMLNS, _attrs,
|
Id = decode_client_id_attrs(__TopXMLNS, _attrs,
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
%% API
|
%% API
|
||||||
-export([add_delay_info/3, add_delay_info/4, unwrap_carbon/1,
|
-export([add_delay_info/3, add_delay_info/4, unwrap_carbon/1,
|
||||||
is_standalone_chat_state/1, get_xdata_values/2,
|
is_standalone_chat_state/1, get_xdata_values/2,
|
||||||
has_xdata_var/2]).
|
has_xdata_var/2, make_adhoc_response/1, make_adhoc_response/2]).
|
||||||
|
|
||||||
-include("xmpp.hrl").
|
-include("xmpp.hrl").
|
||||||
|
|
||||||
@ -88,6 +88,18 @@ get_xdata_values(Var, #xdata{fields = Fields}) ->
|
|||||||
has_xdata_var(Var, #xdata{fields = Fields}) ->
|
has_xdata_var(Var, #xdata{fields = Fields}) ->
|
||||||
lists:keymember(Var, #xdata_field.var, Fields).
|
lists:keymember(Var, #xdata_field.var, Fields).
|
||||||
|
|
||||||
|
-spec make_adhoc_response(adhoc_command(), adhoc_command()) -> adhoc_command().
|
||||||
|
make_adhoc_response(#adhoc_command{lang = Lang, node = Node, sid = SID},
|
||||||
|
Command) ->
|
||||||
|
Command#adhoc_command{lang = Lang, node = Node, sid = SID}.
|
||||||
|
|
||||||
|
-spec make_adhoc_response(adhoc_command()) -> adhoc_command().
|
||||||
|
make_adhoc_response(#adhoc_command{sid = undefined} = Command) ->
|
||||||
|
SID = jlib:now_to_utc_string(p1_time_compat:timestamp()),
|
||||||
|
Command#adhoc_command{sid = SID};
|
||||||
|
make_adhoc_response(Command) ->
|
||||||
|
Command.
|
||||||
|
|
||||||
%%%===================================================================
|
%%%===================================================================
|
||||||
%%% Internal functions
|
%%% Internal functions
|
||||||
%%%===================================================================
|
%%%===================================================================
|
||||||
|
@ -2821,6 +2821,62 @@
|
|||||||
result = {client_id, '$id'},
|
result = {client_id, '$id'},
|
||||||
attrs = [#attr{name = <<"id">>, required = true}]}).
|
attrs = [#attr{name = <<"id">>, required = true}]}).
|
||||||
|
|
||||||
|
-xml(adhoc_command_prev,
|
||||||
|
#elem{name = <<"prev">>,
|
||||||
|
xmlns = <<"http://jabber.org/protocol/commands">>,
|
||||||
|
result = true}).
|
||||||
|
-xml(adhoc_command_next,
|
||||||
|
#elem{name = <<"next">>,
|
||||||
|
xmlns = <<"http://jabber.org/protocol/commands">>,
|
||||||
|
result = true}).
|
||||||
|
-xml(adhoc_command_complete,
|
||||||
|
#elem{name = <<"complete">>,
|
||||||
|
xmlns = <<"http://jabber.org/protocol/commands">>,
|
||||||
|
result = true}).
|
||||||
|
|
||||||
|
-xml(adhoc_command_actions,
|
||||||
|
#elem{name = <<"actions">>,
|
||||||
|
xmlns = <<"http://jabber.org/protocol/commands">>,
|
||||||
|
result = {adhoc_actions, '$execute', '$prev', '$next', '$complete'},
|
||||||
|
attrs = [#attr{name = <<"execute">>,
|
||||||
|
dec = {dec_enum, [[complete, next, prev]]},
|
||||||
|
enc = {enc_enum, []}}],
|
||||||
|
refs = [#ref{name = adhoc_command_prev, min = 0, max = 1,
|
||||||
|
default = false, label = '$prev'},
|
||||||
|
#ref{name = adhoc_command_next, min = 0, max = 1,
|
||||||
|
default = false, label = '$next'},
|
||||||
|
#ref{name = adhoc_command_complete, min = 0, max = 1,
|
||||||
|
default = false, label = '$complete'}]}).
|
||||||
|
|
||||||
|
-xml(adhoc_command_notes,
|
||||||
|
#elem{name = <<"note">>,
|
||||||
|
xmlns = <<"http://jabber.org/protocol/commands">>,
|
||||||
|
result = {adhoc_note, '$type', '$data'},
|
||||||
|
attrs = [#attr{name = <<"type">>, default = info,
|
||||||
|
dec = {dec_enum, [[info, warn, error]]},
|
||||||
|
enc = {enc_enum, []}}],
|
||||||
|
cdata = #cdata{default = <<"">>, label = '$data'}}).
|
||||||
|
|
||||||
|
-xml(adhoc_command,
|
||||||
|
#elem{name = <<"command">>,
|
||||||
|
xmlns = <<"http://jabber.org/protocol/commands">>,
|
||||||
|
result = {adhoc_command, '$node', '$action', '$sid',
|
||||||
|
'$status', '$lang', '$actions', '$notes', '$xdata'},
|
||||||
|
attrs = [#attr{name = <<"node">>, required = true},
|
||||||
|
#attr{name = <<"xml:lang">>, label = '$lang'},
|
||||||
|
#attr{name = <<"sessionid">>, label = '$sid'},
|
||||||
|
#attr{name = <<"status">>,
|
||||||
|
dec = {dec_enum, [[canceled, completed, executing]]},
|
||||||
|
enc = {enc_enum, []}},
|
||||||
|
#attr{name = <<"action">>, default = execute,
|
||||||
|
dec = {dec_enum, [[cancel, complete,
|
||||||
|
execute, next, prev]]},
|
||||||
|
enc = {enc_enum, []}}],
|
||||||
|
refs = [#ref{name = adhoc_command_actions, min = 0, max = 1,
|
||||||
|
label = '$actions'},
|
||||||
|
#ref{name = xdata, min = 0, max = 1},
|
||||||
|
#ref{name = adhoc_command_notes, label = '$notes'}]}).
|
||||||
|
|
||||||
dec_tzo(Val) ->
|
dec_tzo(Val) ->
|
||||||
[H1, M1] = str:tokens(Val, <<":">>),
|
[H1, M1] = str:tokens(Val, <<":">>),
|
||||||
H = jlib:binary_to_integer(H1),
|
H = jlib:binary_to_integer(H1),
|
||||||
|
Loading…
Reference in New Issue
Block a user