-include("ejabberd.hrl").
-include("logger.hrl").
-
--include("jlib.hrl").
+-include("xmpp.hrl").
-include("ejabberd_sm.hrl").
--include("adhoc.hrl").
-define(T(Lang, Text), translate:translate(Lang, Text)).
%%%-----------------------------------------------------------------------
-define(INFO_IDENTITY(Category, Type, Name, Lang),
- [#xmlel{name = <<"identity">>,
- attrs =
- [{<<"category">>, Category}, {<<"type">>, Type},
- {<<"name">>, ?T(Lang, Name)}],
- children = []}]).
+ [#identity{category = Category, type = Type, name = ?T(Lang, Name)}]).
-define(INFO_COMMAND(Name, Lang),
?INFO_IDENTITY(<<"automation">>, <<"command-node">>,
Name, Lang)).
-define(NODEJID(To, Name, Node),
- #xmlel{name = <<"item">>,
- attrs =
- [{<<"jid">>, jid:to_string(To)},
- {<<"name">>, ?T(Lang, Name)}, {<<"node">>, Node}],
- children = []}).
+ #disco_item{jid = To, name = ?T(Lang, Name), node = Node}).
-define(NODE(Name, Node),
- #xmlel{name = <<"item">>,
- attrs =
- [{<<"jid">>, Server}, {<<"name">>, ?T(Lang, Name)},
- {<<"node">>, Node}],
- children = []}).
+ #disco_item{jid = jid:make(Server),
+ node = Node,
+ name = ?T(Lang, Name)}).
-define(NS_ADMINX(Sub),
<<(?NS_ADMIN)/binary, "#", Sub/binary>>).
[<<"http:">>, <<"jabber.org">>, <<"protocol">>,
<<"admin">>, Sub]).
+tokenize(undefined) -> [];
tokenize(Node) -> str:tokens(Node, <<"/#">>).
get_sm_identity(Acc, _From, _To, Node, Lang) ->
-define(INFO_RESULT(Allow, Feats, Lang),
case Allow of
- deny -> {error, ?ERRT_FORBIDDEN(Lang, <<"Denied by ACL">>)};
+ deny -> {error, xmpp:err_forbidden(<<"Denied by ACL">>, Lang)};
allow -> {result, Feats}
end).
{result, Its} -> Its;
empty -> []
end,
- Nodes = [#xmlel{name = <<"item">>,
- attrs =
- [{<<"jid">>, jid:to_string(To)},
- {<<"name">>, ?T(Lang, <<"Configuration">>)},
- {<<"node">>, <<"config">>}],
- children = []}],
+ Nodes = [#disco_item{jid = To, node = <<"config">>,
+ name = ?T(Lang, <<"Configuration">>)}],
{result, Items ++ Nodes};
_ -> Acc
end.
empty -> []
end,
case {acl:match_rule(LServer, configure, From), Node} of
- {allow, <<"">>} ->
+ {allow, undefined} ->
Nodes = [?NODEJID(To, <<"Configuration">>,
<<"config">>),
?NODEJID(To, <<"User Management">>, <<"user">>)],
Items ++ Nodes ++ get_user_resources(User, Server)};
{allow, <<"config">>} -> {result, []};
{_, <<"config">>} ->
- {error, ?ERRT_FORBIDDEN(Lang, <<"Denied by ACL">>)};
+ {error, xmpp:err_forbidden(<<"Denied by ACL">>, Lang)};
_ -> Acc
end
end.
get_user_resources(User, Server) ->
Rs = ejabberd_sm:get_user_resources(User, Server),
lists:map(fun (R) ->
- #xmlel{name = <<"item">>,
- attrs =
- [{<<"jid">>,
- <<User/binary, "@", Server/binary, "/",
- R/binary>>},
- {<<"name">>, User}],
- children = []}
+ #disco_item{jid = jid:make(User, Server, R),
+ name = User}
end,
lists:sort(Rs)).
{result, Res} -> Res;
{error, _Error} -> []
end,
- Nodes = lists:flatten(lists:map(fun (N) ->
- S = fxml:get_tag_attr_s(<<"jid">>,
- N),
- Nd = fxml:get_tag_attr_s(<<"node">>,
- N),
- if (S /= Server) or
- (Nd == <<"">>) ->
- [];
- true ->
- [N,
- recursively_get_local_items(PermLev,
- LServer,
- Nd,
- Server,
- Lang)]
- end
- end,
- Items)),
- Nodes.
+ lists:flatten(
+ lists:map(
+ fun(#disco_item{jid = #jid{server = S}, node = Nd} = Item) ->
+ if (S /= Server) or
+ (Nd == <<"">>) ->
+ [];
+ true ->
+ [Item,
+ recursively_get_local_items(
+ PermLev, LServer, Nd, Server, Lang)]
+ end
+ end,
+ Items)).
get_permission_level(JID) ->
case acl:match_rule(global, configure, JID) of
end).
get_local_items(Acc, From, #jid{lserver = LServer} = To,
- <<"">>, Lang) ->
+ undefined, Lang) ->
case gen_mod:is_loaded(LServer, mod_adhoc) of
false -> Acc;
_ ->
_ ->
LNode = tokenize(Node),
Allow = acl:match_rule(LServer, configure, From),
- Err = ?ERRT_FORBIDDEN(Lang, <<"Denied by ACL">>),
+ Err = xmpp:err_forbidden(<<"Denied by ACL">>, Lang),
case LNode of
[<<"config">>] ->
?ITEMS_RESULT(Allow, LNode, {error, Err});
_Lang) ->
Users = ejabberd_auth:get_vh_registered_users(Host),
SUsers = lists:sort([{S, U} || {U, S} <- Users]),
- case catch begin
- [S1, S2] = ejabberd_regexp:split(Diap, <<"-">>),
- N1 = jlib:binary_to_integer(S1),
- N2 = jlib:binary_to_integer(S2),
- Sub = lists:sublist(SUsers, N1, N2 - N1 + 1),
- lists:map(fun ({S, U}) ->
- #xmlel{name = <<"item">>,
- attrs =
- [{<<"jid">>,
- <<U/binary, "@",
- S/binary>>},
- {<<"name">>,
- <<U/binary, "@",
- S/binary>>}],
- children = []}
- end,
- Sub)
- end
- of
- {'EXIT', _Reason} -> ?ERR_NOT_ACCEPTABLE;
- Res -> {result, Res}
+ try
+ [S1, S2] = ejabberd_regexp:split(Diap, <<"-">>),
+ N1 = jlib:binary_to_integer(S1),
+ N2 = jlib:binary_to_integer(S2),
+ Sub = lists:sublist(SUsers, N1, N2 - N1 + 1),
+ {result, lists:map(
+ fun({S, U}) ->
+ #disco_item{jid = jid:make(U, S),
+ name = <<U/binary, $@, S/binary>>}
+ end, Sub)}
+ catch _:_ ->
+ xmpp:err_not_acceptable()
end;
get_local_items({_, Host}, [<<"outgoing s2s">>],
_Server, Lang) ->
_Lang) ->
{result, []};
get_local_items(_Host, _, _Server, _Lang) ->
- {error, ?ERR_ITEM_NOT_FOUND}.
+ {error, xmpp:err_item_not_found()}.
get_online_vh_users(Host) ->
case catch ejabberd_sm:get_vh_session_list(Host) of
{'EXIT', _Reason} -> [];
USRs ->
SURs = lists:sort([{S, U, R} || {U, S, R} <- USRs]),
- lists:map(fun ({S, U, R}) ->
- #xmlel{name = <<"item">>,
- attrs =
- [{<<"jid">>,
- <<U/binary, "@", S/binary, "/",
- R/binary>>},
- {<<"name">>,
- <<U/binary, "@", S/binary>>}],
- children = []}
- end,
- SURs)
+ lists:map(
+ fun({S, U, R}) ->
+ #disco_item{jid = jid:make(U, S, R),
+ name = <<U/binary, "@", S/binary>>}
+ end, SURs)
end.
get_all_vh_users(Host) ->
SUsers = lists:sort([{S, U} || {U, S} <- Users]),
case length(SUsers) of
N when N =< 100 ->
- lists:map(fun ({S, U}) ->
- #xmlel{name = <<"item">>,
- attrs =
- [{<<"jid">>,
- <<U/binary, "@", S/binary>>},
- {<<"name">>,
- <<U/binary, "@", S/binary>>}],
- children = []}
- end,
- SUsers);
+ lists:map(fun({S, U}) ->
+ #disco_item{jid = jid:make(U, S),
+ name = <<U/binary, $@, S/binary>>}
+ end, SUsers);
N ->
NParts = trunc(math:sqrt(N * 6.17999999999999993783e-1))
+ 1,
end,
Name = <<FU/binary, "@", FS/binary, " -- ",
LU/binary, "@", LS/binary>>,
- #xmlel{name = <<"item">>,
- attrs =
- [{<<"jid">>, Host},
- {<<"node">>,
- <<"all users/", Node/binary>>},
- {<<"name">>, Name}],
- children = []}
+ #disco_item{jid = jid:make(Host),
+ node = <<"all users/", Node/binary>>,
+ name = Name}
end,
lists:seq(1, N, M))
end
TConns = [TH
|| {FH, TH} <- Connections,
Host == FH orelse str:suffix(DotHost, FH)],
- lists:map(fun (T) ->
- #xmlel{name = <<"item">>,
- attrs =
- [{<<"jid">>, Host},
- {<<"node">>,
- <<"outgoing s2s/", T/binary>>},
- {<<"name">>,
- iolist_to_binary(io_lib:format(?T(Lang,
- <<"To ~s">>),
- [T]))}],
- children = []}
- end,
- lists:usort(TConns))
+ lists:map(
+ fun (T) ->
+ Name = iolist_to_binary(
+ io_lib:format(?T(Lang, <<"To ~s">>),[T])),
+ #disco_item{jid = jid:make(Host),
+ node = <<"outgoing s2s/", T/binary>>,
+ name = Name}
+ end, lists:usort(TConns))
end.
get_outgoing_s2s(Host, Lang, To) ->
case catch ejabberd_s2s:dirty_get_connections() of
{'EXIT', _Reason} -> [];
Connections ->
- lists:map(fun ({F, _T}) ->
- #xmlel{name = <<"item">>,
- attrs =
- [{<<"jid">>, Host},
- {<<"node">>,
- <<"outgoing s2s/", To/binary, "/",
- F/binary>>},
- {<<"name">>,
- iolist_to_binary(io_lib:format(?T(Lang,
- <<"From ~s">>),
- [F]))}],
- children = []}
- end,
- lists:keysort(1,
- lists:filter(fun (E) -> element(2, E) == To
- end,
- Connections)))
+ lists:map(
+ fun ({F, _T}) ->
+ Node = <<"outgoing s2s/", To/binary, "/", F/binary>>,
+ Name = iolist_to_binary(
+ io_lib:format(?T(Lang, <<"From ~s">>), [F])),
+ #disco_item{jid = jid:make(Host), node = Node, name = Name}
+ end,
+ lists:keysort(1,
+ lists:filter(fun (E) -> element(2, E) == To
+ end,
+ Connections)))
end.
get_running_nodes(Server, _Lang) ->
case catch mnesia:system_info(running_db_nodes) of
{'EXIT', _Reason} -> [];
DBNodes ->
- lists:map(fun (N) ->
- S = iolist_to_binary(atom_to_list(N)),
- #xmlel{name = <<"item">>,
- attrs =
- [{<<"jid">>, Server},
- {<<"node">>,
- <<"running nodes/", S/binary>>},
- {<<"name">>, S}],
- children = []}
- end,
- lists:sort(DBNodes))
+ lists:map(
+ fun (N) ->
+ S = iolist_to_binary(atom_to_list(N)),
+ #disco_item{jid = jid:make(Server),
+ node = <<"running nodes/", S/binary>>,
+ name = S}
+ end,
+ lists:sort(DBNodes))
end.
get_stopped_nodes(_Lang) ->
of
{'EXIT', _Reason} -> [];
DBNodes ->
- lists:map(fun (N) ->
- S = iolist_to_binary(atom_to_list(N)),
- #xmlel{name = <<"item">>,
- attrs =
- [{<<"jid">>, ?MYNAME},
- {<<"node">>,
- <<"stopped nodes/", S/binary>>},
- {<<"name">>, S}],
- children = []}
- end,
- lists:sort(DBNodes))
+ lists:map(
+ fun (N) ->
+ S = iolist_to_binary(atom_to_list(N)),
+ #disco_item{jid = jid:make(?MYNAME),
+ node = <<"stopped nodes/", S/binary>>,
+ name = S}
+ end,
+ lists:sort(DBNodes))
end.
%%-------------------------------------------------------------------------
-define(COMMANDS_RESULT(LServerOrGlobal, From, To,
Request, Lang),
case acl:match_rule(LServerOrGlobal, configure, From) of
- deny -> {error, ?ERRT_FORBIDDEN(Lang, <<"Denied by ACL">>)};
+ deny -> {error, xmpp:err_forbidden(<<"Denied by ACL">>, Lang)};
allow -> adhoc_local_commands(From, To, Request)
end).
adhoc_local_commands(Acc, From,
#jid{lserver = LServer} = To,
- #adhoc_request{node = Node, lang = Lang} = Request) ->
+ #adhoc_command{node = Node, lang = Lang} = Request) ->
LNode = tokenize(Node),
case LNode of
[<<"running nodes">>, _ENode, <<"DB">>] ->
adhoc_local_commands(From,
#jid{lserver = LServer} = _To,
- #adhoc_request{lang = Lang, node = Node,
- sessionid = SessionID, action = Action,
- xdata = XData} =
- Request) ->
+ #adhoc_command{lang = Lang, node = Node,
+ sid = SessionID, action = Action,
+ xdata = XData} = Request) ->
LNode = tokenize(Node),
- ActionIsExecute = lists:member(Action,
- [<<"">>, <<"execute">>, <<"complete">>]),
- if Action == <<"cancel">> ->
- adhoc:produce_response(Request,
- #adhoc_response{status = canceled});
- XData == false, ActionIsExecute ->
+ ActionIsExecute = Action == execute orelse Action == complete,
+ if Action == cancel ->
+ #adhoc_command{status = canceled, lang = Lang,
+ node = Node, sid = SessionID};
+ XData == undefined, ActionIsExecute ->
case get_form(LServer, LNode, Lang) of
{result, Form} ->
- adhoc:produce_response(Request,
- #adhoc_response{status = executing,
- elements = Form});
+ xmpp_util:make_adhoc_response(
+ Request,
+ #adhoc_command{status = executing, xdata = Form});
{result, Status, Form} ->
- adhoc:produce_response(Request,
- #adhoc_response{status = Status,
- elements = Form});
+ xmpp_util:make_adhoc_response(
+ Request,
+ #adhoc_command{status = Status, xdata = Form});
{error, Error} -> {error, Error}
end;
- XData /= false, ActionIsExecute ->
- case jlib:parse_xdata_submit(XData) of
- invalid ->
- {error, ?ERRT_BAD_REQUEST(Lang, <<"Incorrect data form">>)};
- Fields ->
- case catch set_form(From, LServer, LNode, Lang, Fields)
- of
- {result, Res} ->
- adhoc:produce_response(#adhoc_response{lang = Lang,
- node = Node,
- sessionid =
- SessionID,
- elements = Res,
- status =
- completed});
- {'EXIT', _} -> {error, ?ERR_BAD_REQUEST};
- {error, Error} -> {error, Error}
- end
- end;
+ XData /= undefined, ActionIsExecute ->
+ case catch set_form(From, LServer, LNode, Lang, XData) of
+ {result, Res} ->
+ xmpp_util:make_adhoc_response(
+ Request,
+ #adhoc_command{xdata = Res, status = completed});
+ {'EXIT', _} -> {error, xmpp:err_bad_request()};
+ {error, Error} -> {error, Error}
+ end;
true ->
- {error, ?ERRT_BAD_REQUEST(Lang, <<"Incorrect action or data form">>)}
+ {error, xmpp:err_bad_request(<<"Unexpected action">>, Lang)}
end.
-define(TVFIELD(Type, Var, Val),
- #xmlel{name = <<"field">>,
- attrs = [{<<"type">>, Type}, {<<"var">>, Var}],
- children =
- [#xmlel{name = <<"value">>, attrs = [],
- children = [{xmlcdata, Val}]}]}).
+ #xdata_field{type = Type, var = Var, values = [Val]}).
-define(HFIELD(),
- ?TVFIELD(<<"hidden">>, <<"FORM_TYPE">>, (?NS_ADMIN))).
+ ?TVFIELD(hidden, <<"FORM_TYPE">>, (?NS_ADMIN))).
-define(TLFIELD(Type, Label, Var),
- #xmlel{name = <<"field">>,
- attrs =
- [{<<"type">>, Type}, {<<"label">>, ?T(Lang, Label)},
- {<<"var">>, Var}],
- children = []}).
+ #xdata_field{type = Type, label = ?T(Lang, Label), var = Var}).
-define(XFIELD(Type, Label, Var, Val),
- #xmlel{name = <<"field">>,
- attrs =
- [{<<"type">>, Type}, {<<"label">>, ?T(Lang, Label)},
- {<<"var">>, Var}],
- children =
- [#xmlel{name = <<"value">>, attrs = [],
- children = [{xmlcdata, Val}]}]}).
+ #xdata_field{type = Type, label = ?T(Lang, Label),
+ var = Var, values = [Val]}).
-define(XMFIELD(Type, Label, Var, Vals),
- #xmlel{name = <<"field">>,
- attrs =
- [{<<"type">>, Type}, {<<"label">>, ?T(Lang, Label)},
- {<<"var">>, Var}],
- children =
- [#xmlel{name = <<"value">>, attrs = [],
- children = [{xmlcdata, Val}]}
- || Val <- Vals]}).
+ #xdata_field{type = Type, label = ?T(Lang, Label),
+ var = Var, values = Vals}).
-define(TABLEFIELD(Table, Val),
- #xmlel{name = <<"field">>,
- attrs =
- [{<<"type">>, <<"list-single">>},
- {<<"label">>, iolist_to_binary(atom_to_list(Table))},
- {<<"var">>, iolist_to_binary(atom_to_list(Table))}],
- children =
- [#xmlel{name = <<"value">>, attrs = [],
- children =
- [{xmlcdata,
- iolist_to_binary(atom_to_list(Val))}]},
- #xmlel{name = <<"option">>,
- attrs = [{<<"label">>, ?T(Lang, <<"RAM copy">>)}],
- children =
- [#xmlel{name = <<"value">>, attrs = [],
- children =
- [{xmlcdata, <<"ram_copies">>}]}]},
- #xmlel{name = <<"option">>,
- attrs =
- [{<<"label">>,
- ?T(Lang, <<"RAM and disc copy">>)}],
- children =
- [#xmlel{name = <<"value">>, attrs = [],
- children =
- [{xmlcdata, <<"disc_copies">>}]}]},
- #xmlel{name = <<"option">>,
- attrs =
- [{<<"label">>, ?T(Lang, <<"Disc only copy">>)}],
- children =
- [#xmlel{name = <<"value">>, attrs = [],
- children =
- [{xmlcdata,
- <<"disc_only_copies">>}]}]},
- #xmlel{name = <<"option">>,
- attrs = [{<<"label">>, ?T(Lang, <<"Remote copy">>)}],
- children =
- [#xmlel{name = <<"value">>, attrs = [],
- children =
- [{xmlcdata, <<"unknown">>}]}]}]}).
+ #xdata_field{
+ type = 'list-single',
+ label = iolist_to_binary(atom_to_list(Table)),
+ var = iolist_to_binary(atom_to_list(Table)),
+ values = [iolist_to_binary(atom_to_list(Val))],
+ options = [#xdata_option{label = ?T(Lang, <<"RAM copy">>),
+ value = <<"ram_copies">>},
+ #xdata_option{label = ?T(Lang, <<"RAM and disc copy">>),
+ value = <<"disc_copies">>},
+ #xdata_option{label = ?T(Lang, <<"Disc only copy">>),
+ value = <<"disc_only_copies">>},
+ #xdata_option{label = ?T(Lang, <<"Remote copy">>),
+ value = <<"unknown">>}]}).
get_form(_Host, [<<"running nodes">>, ENode, <<"DB">>],
Lang) ->
case search_running_node(ENode) of
false ->
Txt = <<"No running node found">>,
- {error, ?ERRT_ITEM_NOT_FOUND(Lang, Txt)};
+ {error, xmpp:err_item_not_found(Txt, Lang)};
Node ->
case ejabberd_cluster:call(Node, mnesia, system_info, [tables]) of
{badrpc, Reason} ->
?ERROR_MSG("RPC call mnesia:system_info(tables) on node "
"~s failed: ~p", [Node, Reason]),
- {error, ?ERR_INTERNAL_SERVER_ERROR};
+ {error, xmpp:err_internal_server_error()};
Tables ->
STables = lists:sort(Tables),
- {result,
- [#xmlel{name = <<"x">>,
- attrs = [{<<"xmlns">>, ?NS_XDATA}],
- children =
- [?HFIELD(),
- #xmlel{name = <<"title">>, attrs = [],
- children =
- [{xmlcdata,
- <<(?T(Lang,
- <<"Database Tables Configuration at ">>))/binary,
- ENode/binary>>}]},
- #xmlel{name = <<"instructions">>, attrs = [],
- children =
- [{xmlcdata,
- ?T(Lang,
- <<"Choose storage type of tables">>)}]}
- | lists:map(fun (Table) ->
- case ejabberd_cluster:call(Node, mnesia,
- table_info,
- [Table,
- storage_type])
- of
- {badrpc, _} ->
- ?TABLEFIELD(Table,
- unknown);
- Type ->
- ?TABLEFIELD(Table, Type)
- end
- end,
- STables)]}]}
+ Title = <<(?T(Lang, <<"Database Tables Configuration at ">>))/binary,
+ ENode/binary>>,
+ Instr = ?T(Lang, <<"Choose storage type of tables">>),
+ try
+ Fs = lists:map(
+ fun(Table) ->
+ case ejabberd_cluster:call(
+ Node, mnesia, table_info,
+ [Table, storage_type]) of
+ Type when is_atom(Type) ->
+ ?TABLEFIELD(Table, Type)
+ end
+ end, STables),
+ {result, #xdata{title = Title,
+ type = form,
+ instructions = [Instr],
+ fields = [?HFIELD()|Fs]}}
+ catch _:{case_clause, {badrpc, Reason}} ->
+ ?ERROR_MSG("RPC call mnesia:table_info/2 "
+ "on node ~s failed: ~p", [Node, Reason]),
+ {error, xmpp:err_internal_server_error()}
+ end
end
end;
get_form(Host,
case search_running_node(ENode) of
false ->
Txt = <<"No running node found">>,
- {error, ?ERRT_ITEM_NOT_FOUND(Lang, Txt)};
+ {error, xmpp:err_item_not_found(Txt, Lang)};
Node ->
case ejabberd_cluster:call(Node, gen_mod, loaded_modules, [Host]) of
{badrpc, Reason} ->
?ERROR_MSG("RPC call gen_mod:loaded_modules(~s) on node "
"~s failed: ~p", [Host, Node, Reason]),
- {error, ?ERR_INTERNAL_SERVER_ERROR};
+ {error, xmpp:err_internal_server_error()};
Modules ->
SModules = lists:sort(Modules),
- {result,
- [#xmlel{name = <<"x">>,
- attrs = [{<<"xmlns">>, ?NS_XDATA}],
- children =
- [?HFIELD(),
- #xmlel{name = <<"title">>, attrs = [],
- children =
- [{xmlcdata,
- <<(?T(Lang,
- <<"Stop Modules at ">>))/binary,
- ENode/binary>>}]},
- #xmlel{name = <<"instructions">>, attrs = [],
- children =
- [{xmlcdata,
- ?T(Lang,
- <<"Choose modules to stop">>)}]}
- | lists:map(fun (M) ->
- S = jlib:atom_to_binary(M),
- ?XFIELD(<<"boolean">>, S, S,
- <<"0">>)
- end,
- SModules)]}]}
+ Title = <<(?T(Lang, <<"Stop Modules at ">>))/binary,
+ ENode/binary>>,
+ Instr = ?T(Lang, <<"Choose modules to stop">>),
+ Fs = lists:map(fun(M) ->
+ S = jlib:atom_to_binary(M),
+ ?XFIELD(boolean, S, S, <<"0">>)
+ end, SModules),
+ {result, #xdata{title = Title,
+ type = form,
+ instructions = [Instr],
+ fields = [?HFIELD()|Fs]}}
end
end;
get_form(_Host,
<<"start">>],
Lang) ->
{result,
- [#xmlel{name = <<"x">>,
- attrs = [{<<"xmlns">>, ?NS_XDATA}],
- children =
- [?HFIELD(),
- #xmlel{name = <<"title">>, attrs = [],
- children =
- [{xmlcdata,
- <<(?T(Lang, <<"Start Modules at ">>))/binary,
- ENode/binary>>}]},
- #xmlel{name = <<"instructions">>, attrs = [],
- children =
- [{xmlcdata,
- ?T(Lang,
- <<"Enter list of {Module, [Options]}">>)}]},
- ?XFIELD(<<"text-multi">>,
- <<"List of modules to start">>, <<"modules">>,
- <<"[].">>)]}]};
+ #xdata{title = <<(?T(Lang, <<"Start Modules at ">>))/binary, ENode/binary>>,
+ type = form,
+ instructions = [?T(Lang, <<"Enter list of {Module, [Options]}">>)],
+ fields = [?HFIELD(),
+ ?XFIELD('text-multi',
+ <<"List of modules to start">>, <<"modules">>,
+ <<"[].">>)]}};
get_form(_Host,
[<<"running nodes">>, ENode, <<"backup">>,
<<"backup">>],
Lang) ->
{result,
- [#xmlel{name = <<"x">>,
- attrs = [{<<"xmlns">>, ?NS_XDATA}],
- children =
- [?HFIELD(),
- #xmlel{name = <<"title">>, attrs = [],
- children =
- [{xmlcdata,
- <<(?T(Lang, <<"Backup to File at ">>))/binary,
- ENode/binary>>}]},
- #xmlel{name = <<"instructions">>, attrs = [],
- children =
- [{xmlcdata,
- ?T(Lang, <<"Enter path to backup file">>)}]},
- ?XFIELD(<<"text-single">>, <<"Path to File">>,
- <<"path">>, <<"">>)]}]};
+ #xdata{title = <<(?T(Lang, <<"Backup to File at ">>))/binary, ENode/binary>>,
+ type = form,
+ instructions = [?T(Lang, <<"Enter path to backup file">>)],
+ fields = [?HFIELD(),
+ ?XFIELD('text-single', <<"Path to File">>,
+ <<"path">>, <<"">>)]}};
get_form(_Host,
[<<"running nodes">>, ENode, <<"backup">>,
<<"restore">>],
Lang) ->
{result,
- [#xmlel{name = <<"x">>,
- attrs = [{<<"xmlns">>, ?NS_XDATA}],
- children =
- [?HFIELD(),
- #xmlel{name = <<"title">>, attrs = [],
- children =
- [{xmlcdata,
- <<(?T(Lang,
- <<"Restore Backup from File at ">>))/binary,
- ENode/binary>>}]},
- #xmlel{name = <<"instructions">>, attrs = [],
- children =
- [{xmlcdata,
- ?T(Lang, <<"Enter path to backup file">>)}]},
- ?XFIELD(<<"text-single">>, <<"Path to File">>,
- <<"path">>, <<"">>)]}]};
+ #xdata{title = <<(?T(Lang, <<"Restore Backup from File at ">>))/binary,
+ ENode/binary>>,
+ type = form,
+ instructions = [?T(Lang, <<"Enter path to backup file">>)],
+ fields = [?HFIELD(),
+ ?XFIELD('text-single', <<"Path to File">>,
+ <<"path">>, <<"">>)]}};
get_form(_Host,
[<<"running nodes">>, ENode, <<"backup">>,
<<"textfile">>],
Lang) ->
{result,
- [#xmlel{name = <<"x">>,
- attrs = [{<<"xmlns">>, ?NS_XDATA}],
- children =
- [?HFIELD(),
- #xmlel{name = <<"title">>, attrs = [],
- children =
- [{xmlcdata,
- <<(?T(Lang,
- <<"Dump Backup to Text File at ">>))/binary,
- ENode/binary>>}]},
- #xmlel{name = <<"instructions">>, attrs = [],
- children =
- [{xmlcdata,
- ?T(Lang, <<"Enter path to text file">>)}]},
- ?XFIELD(<<"text-single">>, <<"Path to File">>,
- <<"path">>, <<"">>)]}]};
+ #xdata{title = <<(?T(Lang, <<"Dump Backup to Text File at ">>))/binary,
+ ENode/binary>>,
+ type = form,
+ instructions = [?T(Lang, <<"Enter path to text file">>)],
+ fields = [?HFIELD(),
+ ?XFIELD('text-single', <<"Path to File">>,
+ <<"path">>, <<"">>)]}};
get_form(_Host,
[<<"running nodes">>, ENode, <<"import">>, <<"file">>],
Lang) ->
{result,
- [#xmlel{name = <<"x">>,
- attrs = [{<<"xmlns">>, ?NS_XDATA}],
- children =
- [?HFIELD(),
- #xmlel{name = <<"title">>, attrs = [],
- children =
- [{xmlcdata,
- <<(?T(Lang,
- <<"Import User from File at ">>))/binary,
- ENode/binary>>}]},
- #xmlel{name = <<"instructions">>, attrs = [],
- children =
- [{xmlcdata,
- ?T(Lang,
- <<"Enter path to jabberd14 spool file">>)}]},
- ?XFIELD(<<"text-single">>, <<"Path to File">>,
- <<"path">>, <<"">>)]}]};
+ #xdata{title = <<(?T(Lang, <<"Import User from File at ">>))/binary,
+ ENode/binary>>,
+ type = form,
+ instructions = [?T(Lang, <<"Enter path to jabberd14 spool file">>)],
+ fields = [?HFIELD(),
+ ?XFIELD('text-single', <<"Path to File">>,
+ <<"path">>, <<"">>)]}};
get_form(_Host,
[<<"running nodes">>, ENode, <<"import">>, <<"dir">>],
Lang) ->
{result,
- [#xmlel{name = <<"x">>,
- attrs = [{<<"xmlns">>, ?NS_XDATA}],
- children =
- [?HFIELD(),
- #xmlel{name = <<"title">>, attrs = [],
- children =
- [{xmlcdata,
- <<(?T(Lang,
- <<"Import Users from Dir at ">>))/binary,
- ENode/binary>>}]},
- #xmlel{name = <<"instructions">>, attrs = [],
- children =
- [{xmlcdata,
- ?T(Lang,
- <<"Enter path to jabberd14 spool dir">>)}]},
- ?XFIELD(<<"text-single">>, <<"Path to Dir">>,
- <<"path">>, <<"">>)]}]};
+ #xdata{title = <<(?T(Lang, <<"Import Users from Dir at ">>))/binary,
+ ENode/binary>>,
+ type = form,
+ instructions = [?T(Lang, <<"Enter path to jabberd14 spool dir">>)],
+ fields = [?HFIELD(),
+ ?XFIELD('text-single', <<"Path to Dir">>,
+ <<"path">>, <<"">>)]}};
get_form(_Host,
[<<"running nodes">>, _ENode, <<"restart">>], Lang) ->
- Make_option = fun (LabelNum, LabelUnit, Value) ->
- #xmlel{name = <<"option">>,
- attrs =
- [{<<"label">>,
- <<LabelNum/binary,
- (?T(Lang, LabelUnit))/binary>>}],
- children =
- [#xmlel{name = <<"value">>, attrs = [],
- children = [{xmlcdata, Value}]}]}
- end,
+ Make_option =
+ fun (LabelNum, LabelUnit, Value) ->
+ #xdata_option{
+ label = <<LabelNum/binary, (?T(Lang, LabelUnit))/binary>>,
+ value = Value}
+ end,
{result,
- [#xmlel{name = <<"x">>,
- attrs = [{<<"xmlns">>, ?NS_XDATA}],
- children =
- [?HFIELD(),
- #xmlel{name = <<"title">>, attrs = [],
- children =
- [{xmlcdata, ?T(Lang, <<"Restart Service">>)}]},
- #xmlel{name = <<"field">>,
- attrs =
- [{<<"type">>, <<"list-single">>},
- {<<"label">>, ?T(Lang, <<"Time delay">>)},
- {<<"var">>, <<"delay">>}],
- children =
+ #xdata{title = ?T(Lang, <<"Restart Service">>),
+ type = form,
+ fields = [?HFIELD(),
+ #xdata_field{
+ type = 'list-single',
+ label = ?T(Lang, <<"Time delay">>),
+ var = <<"delay">>,
+ required = true,
+ options =
[Make_option(<<"">>, <<"immediately">>, <<"1">>),
Make_option(<<"15 ">>, <<"seconds">>, <<"15">>),
Make_option(<<"30 ">>, <<"seconds">>, <<"30">>),
Make_option(<<"5 ">>, <<"minutes">>, <<"300">>),
Make_option(<<"10 ">>, <<"minutes">>, <<"600">>),
Make_option(<<"15 ">>, <<"minutes">>, <<"900">>),
- Make_option(<<"30 ">>, <<"minutes">>, <<"1800">>),
- #xmlel{name = <<"required">>, attrs = [],
- children = []}]},
- #xmlel{name = <<"field">>,
- attrs =
- [{<<"type">>, <<"fixed">>},
- {<<"label">>,
- ?T(Lang,
- <<"Send announcement to all online users "
- "on all hosts">>)}],
- children = []},
- #xmlel{name = <<"field">>,
- attrs =
- [{<<"var">>, <<"subject">>},
- {<<"type">>, <<"text-single">>},
- {<<"label">>, ?T(Lang, <<"Subject">>)}],
- children = []},
- #xmlel{name = <<"field">>,
- attrs =
- [{<<"var">>, <<"announcement">>},
- {<<"type">>, <<"text-multi">>},
- {<<"label">>, ?T(Lang, <<"Message body">>)}],
- children = []}]}]};
+ Make_option(<<"30 ">>, <<"minutes">>, <<"1800">>)]},
+ #xdata_field{type = fixed,
+ label = ?T(Lang,
+ <<"Send announcement to all online users "
+ "on all hosts">>)},
+ #xdata_field{var = <<"subject">>,
+ type = 'text-single',
+ label = ?T(Lang, <<"Subject">>)},
+ #xdata_field{var = <<"announcement">>,
+ type = 'text-multi',
+ label = ?T(Lang, <<"Message body">>)}]}};
get_form(_Host,
[<<"running nodes">>, _ENode, <<"shutdown">>], Lang) ->
- Make_option = fun (LabelNum, LabelUnit, Value) ->
- #xmlel{name = <<"option">>,
- attrs =
- [{<<"label">>,
- <<LabelNum/binary,
- (?T(Lang, LabelUnit))/binary>>}],
- children =
- [#xmlel{name = <<"value">>, attrs = [],
- children = [{xmlcdata, Value}]}]}
- end,
+ Make_option =
+ fun (LabelNum, LabelUnit, Value) ->
+ #xdata_option{
+ label = <<LabelNum/binary, (?T(Lang, LabelUnit))/binary>>,
+ value = Value}
+ end,
{result,
- [#xmlel{name = <<"x">>,
- attrs = [{<<"xmlns">>, ?NS_XDATA}],
- children =
- [?HFIELD(),
- #xmlel{name = <<"title">>, attrs = [],
- children =
- [{xmlcdata, ?T(Lang, <<"Shut Down Service">>)}]},
- #xmlel{name = <<"field">>,
- attrs =
- [{<<"type">>, <<"list-single">>},
- {<<"label">>, ?T(Lang, <<"Time delay">>)},
- {<<"var">>, <<"delay">>}],
- children =
+ #xdata{title = ?T(Lang, <<"Shut Down Service">>),
+ type = form,
+ fields = [?HFIELD(),
+ #xdata_field{
+ type = 'list-single',
+ label = ?T(Lang, <<"Time delay">>),
+ var = <<"delay">>,
+ required = true,
+ options =
[Make_option(<<"">>, <<"immediately">>, <<"1">>),
Make_option(<<"15 ">>, <<"seconds">>, <<"15">>),
Make_option(<<"30 ">>, <<"seconds">>, <<"30">>),
Make_option(<<"5 ">>, <<"minutes">>, <<"300">>),
Make_option(<<"10 ">>, <<"minutes">>, <<"600">>),
Make_option(<<"15 ">>, <<"minutes">>, <<"900">>),
- Make_option(<<"30 ">>, <<"minutes">>, <<"1800">>),
- #xmlel{name = <<"required">>, attrs = [],
- children = []}]},
- #xmlel{name = <<"field">>,
- attrs =
- [{<<"type">>, <<"fixed">>},
- {<<"label">>,
- ?T(Lang,
- <<"Send announcement to all online users "
- "on all hosts">>)}],
- children = []},
- #xmlel{name = <<"field">>,
- attrs =
- [{<<"var">>, <<"subject">>},
- {<<"type">>, <<"text-single">>},
- {<<"label">>, ?T(Lang, <<"Subject">>)}],
- children = []},
- #xmlel{name = <<"field">>,
- attrs =
- [{<<"var">>, <<"announcement">>},
- {<<"type">>, <<"text-multi">>},
- {<<"label">>, ?T(Lang, <<"Message body">>)}],
- children = []}]}]};
+ Make_option(<<"30 ">>, <<"minutes">>, <<"1800">>)]},
+ #xdata_field{type = fixed,
+ label = ?T(Lang,
+ <<"Send announcement to all online users "
+ "on all hosts">>)},
+ #xdata_field{var = <<"subject">>,
+ type = 'text-single',
+ label = ?T(Lang, <<"Subject">>)},
+ #xdata_field{var = <<"announcement">>,
+ type = 'text-multi',
+ label = ?T(Lang, <<"Message body">>)}]}};
get_form(Host, [<<"config">>, <<"acls">>], Lang) ->
+ ACLs = str:tokens(
+ iolist_to_binary(
+ io_lib:format("~p.",
+ [ets:select(
+ acl,
+ ets:fun2ms(
+ fun({acl, {Name, H}, Spec}) when H == Host ->
+ {acl, Name, Spec}
+ end))])),
+ <<"\n">>),
{result,
- [#xmlel{name = <<"x">>,
- attrs = [{<<"xmlns">>, ?NS_XDATA}],
- children =
- [?HFIELD(),
- #xmlel{name = <<"title">>, attrs = [],
- children =
- [{xmlcdata,
- ?T(Lang,
- <<"Access Control List Configuration">>)}]},
- #xmlel{name = <<"field">>,
- attrs =
- [{<<"type">>, <<"text-multi">>},
- {<<"label">>,
- ?T(Lang, <<"Access control lists">>)},
- {<<"var">>, <<"acls">>}],
- children =
- lists:map(fun (S) ->
- #xmlel{name = <<"value">>,
- attrs = [],
- children =
- [{xmlcdata, S}]}
- end,
- str:tokens(iolist_to_binary(io_lib:format("~p.",
- [ets:select(acl,
- [{{acl,
- {'$1',
- '$2'},
- '$3'},
- [{'==',
- '$2',
- Host}],
- [{{acl,
- '$1',
- '$3'}}]}])])),
- <<"\n">>))}]}]};
+ #xdata{title = ?T(Lang, <<"Access Control List Configuration">>),
+ type = form,
+ fields = [?HFIELD(),
+ #xdata_field{type = 'text-multi',
+ label = ?T(Lang, <<"Access control lists">>),
+ var = <<"acls">>,
+ values = ACLs}]}};
get_form(Host, [<<"config">>, <<"access">>], Lang) ->
+ Accs = str:tokens(
+ iolist_to_binary(
+ io_lib:format("~p.",
+ [ets:select(
+ access,
+ ets:fun2ms(
+ fun({access, {Name, H}, Acc}) when H == Host ->
+ {access, Name, Acc}
+ end))])),
+ <<"\n">>),
{result,
- [#xmlel{name = <<"x">>,
- attrs = [{<<"xmlns">>, ?NS_XDATA}],
- children =
- [?HFIELD(),
- #xmlel{name = <<"title">>, attrs = [],
- children =
- [{xmlcdata,
- ?T(Lang, <<"Access Configuration">>)}]},
- #xmlel{name = <<"field">>,
- attrs =
- [{<<"type">>, <<"text-multi">>},
- {<<"label">>, ?T(Lang, <<"Access rules">>)},
- {<<"var">>, <<"access">>}],
- children =
- lists:map(fun (S) ->
- #xmlel{name = <<"value">>,
- attrs = [],
- children =
- [{xmlcdata, S}]}
- end,
- str:tokens(iolist_to_binary(io_lib:format("~p.",
- [ets:select(access,
- [{{access,
- {'$1',
- '$2'},
- '$3'},
- [{'==',
- '$2',
- Host}],
- [{{access,
- '$1',
- '$3'}}]}])])),
- <<"\n">>))}]}]};
+ #xdata{title = ?T(Lang, <<"Access Configuration">>),
+ type = form,
+ fields = [?HFIELD(),
+ #xdata_field{type = 'text-multi',
+ label = ?T(Lang, <<"Access rules">>),
+ var = <<"access">>,
+ values = Accs}]}};
get_form(_Host, ?NS_ADMINL(<<"add-user">>), Lang) ->
{result,
- [#xmlel{name = <<"x">>,
- attrs = [{<<"xmlns">>, ?NS_XDATA}],
- children =
- [?HFIELD(),
- #xmlel{name = <<"title">>, attrs = [],
- children = [{xmlcdata, ?T(Lang, <<"Add User">>)}]},
- #xmlel{name = <<"field">>,
- attrs =
- [{<<"type">>, <<"jid-single">>},
- {<<"label">>, ?T(Lang, <<"Jabber ID">>)},
- {<<"var">>, <<"accountjid">>}],
- children =
- [#xmlel{name = <<"required">>, attrs = [],
- children = []}]},
- #xmlel{name = <<"field">>,
- attrs =
- [{<<"type">>, <<"text-private">>},
- {<<"label">>, ?T(Lang, <<"Password">>)},
- {<<"var">>, <<"password">>}],
- children =
- [#xmlel{name = <<"required">>, attrs = [],
- children = []}]},
- #xmlel{name = <<"field">>,
- attrs =
- [{<<"type">>, <<"text-private">>},
- {<<"label">>,
- ?T(Lang, <<"Password Verification">>)},
- {<<"var">>, <<"password-verify">>}],
- children =
- [#xmlel{name = <<"required">>, attrs = [],
- children = []}]}]}]};
+ #xdata{title = ?T(Lang, <<"Add User">>),
+ type = form,
+ fields = [?HFIELD(),
+ #xdata_field{type = 'jid-single',
+ label = ?T(Lang, <<"Jabber ID">>),
+ required = true,
+ var = <<"accountjid">>},
+ #xdata_field{type = 'text-private',
+ label = ?T(Lang, <<"Password">>),
+ required = true,
+ var = <<"password">>},
+ #xdata_field{type = 'text-private',
+ label = ?T(Lang, <<"Password Verification">>),
+ required = true,
+ var = <<"password-verify">>}]}};
get_form(_Host, ?NS_ADMINL(<<"delete-user">>), Lang) ->
{result,
- [#xmlel{name = <<"x">>,
- attrs = [{<<"xmlns">>, ?NS_XDATA}],
- children =
- [?HFIELD(),
- #xmlel{name = <<"title">>, attrs = [],
- children = [{xmlcdata, ?T(Lang, <<"Delete User">>)}]},
- #xmlel{name = <<"field">>,
- attrs =
- [{<<"type">>, <<"jid-multi">>},
- {<<"label">>, ?T(Lang, <<"Jabber ID">>)},
- {<<"var">>, <<"accountjids">>}],
- children =
- [#xmlel{name = <<"required">>, attrs = [],
- children = []}]}]}]};
+ #xdata{title = ?T(Lang, <<"Delete User">>),
+ type = form,
+ fields = [?HFIELD(),
+ #xdata_field{type = 'jid-multi',
+ label = ?T(Lang, <<"Jabber ID">>),
+ required = true,
+ var = <<"accountjids">>}]}};
get_form(_Host, ?NS_ADMINL(<<"end-user-session">>),
Lang) ->
{result,
- [#xmlel{name = <<"x">>,
- attrs = [{<<"xmlns">>, ?NS_XDATA}],
- children =
- [?HFIELD(),
- #xmlel{name = <<"title">>, attrs = [],
- children =
- [{xmlcdata, ?T(Lang, <<"End User Session">>)}]},
- #xmlel{name = <<"field">>,
- attrs =
- [{<<"type">>, <<"jid-single">>},
- {<<"label">>, ?T(Lang, <<"Jabber ID">>)},
- {<<"var">>, <<"accountjid">>}],
- children =
- [#xmlel{name = <<"required">>, attrs = [],
- children = []}]}]}]};
+ #xdata{title = ?T(Lang, <<"End User Session">>),
+ type = form,
+ fields = [?HFIELD(),
+ #xdata_field{type = 'jid-single',
+ label = ?T(Lang, <<"Jabber ID">>),
+ required = true,
+ var = <<"accountjid">>}]}};
get_form(_Host, ?NS_ADMINL(<<"get-user-password">>),
Lang) ->
{result,
- [#xmlel{name = <<"x">>,
- attrs = [{<<"xmlns">>, ?NS_XDATA}],
- children =
- [?HFIELD(),
- #xmlel{name = <<"title">>, attrs = [],
- children =
- [{xmlcdata, ?T(Lang, <<"Get User Password">>)}]},
- #xmlel{name = <<"field">>,
- attrs =
- [{<<"type">>, <<"jid-single">>},
- {<<"label">>, ?T(Lang, <<"Jabber ID">>)},
- {<<"var">>, <<"accountjid">>}],
- children =
- [#xmlel{name = <<"required">>, attrs = [],
- children = []}]}]}]};
+ #xdata{title = ?T(Lang, <<"Get User Password">>),
+ type = form,
+ fields = [?HFIELD(),
+ #xdata_field{type = 'jid-single',
+ label = ?T(Lang, <<"Jabber ID">>),
+ var = <<"accountjid">>,
+ required = true}]}};
get_form(_Host, ?NS_ADMINL(<<"change-user-password">>),
Lang) ->
{result,
- [#xmlel{name = <<"x">>,
- attrs = [{<<"xmlns">>, ?NS_XDATA}],
- children =
- [?HFIELD(),
- #xmlel{name = <<"title">>, attrs = [],
- children =
- [{xmlcdata, ?T(Lang, <<"Get User Password">>)}]},
- #xmlel{name = <<"field">>,
- attrs =
- [{<<"type">>, <<"jid-single">>},
- {<<"label">>, ?T(Lang, <<"Jabber ID">>)},
- {<<"var">>, <<"accountjid">>}],
- children =
- [#xmlel{name = <<"required">>, attrs = [],
- children = []}]},
- #xmlel{name = <<"field">>,
- attrs =
- [{<<"type">>, <<"text-private">>},
- {<<"label">>, ?T(Lang, <<"Password">>)},
- {<<"var">>, <<"password">>}],
- children =
- [#xmlel{name = <<"required">>, attrs = [],
- children = []}]}]}]};
+ #xdata{title = ?T(Lang, <<"Get User Password">>),
+ type = form,
+ fields = [?HFIELD(),
+ #xdata_field{type = 'jid-single',
+ label = ?T(Lang, <<"Jabber ID">>),
+ required = true,
+ var = <<"accountjid">>},
+ #xdata_field{type = 'text-private',
+ label = ?T(Lang, <<"Password">>),
+ required = true,
+ var = <<"password">>}]}};
get_form(_Host, ?NS_ADMINL(<<"get-user-lastlogin">>),
Lang) ->
{result,
- [#xmlel{name = <<"x">>,
- attrs = [{<<"xmlns">>, ?NS_XDATA}],
- children =
- [?HFIELD(),
- #xmlel{name = <<"title">>, attrs = [],
- children =
- [{xmlcdata,
- ?T(Lang, <<"Get User Last Login Time">>)}]},
- #xmlel{name = <<"field">>,
- attrs =
- [{<<"type">>, <<"jid-single">>},
- {<<"label">>, ?T(Lang, <<"Jabber ID">>)},
- {<<"var">>, <<"accountjid">>}],
- children =
- [#xmlel{name = <<"required">>, attrs = [],
- children = []}]}]}]};
+ #xdata{title = ?T(Lang, <<"Get User Last Login Time">>),
+ type = form,
+ fields = [?HFIELD(),
+ #xdata_field{type = 'jid-single',
+ label = ?T(Lang, <<"Jabber ID">>),
+ var = <<"accountjid">>,
+ required = true}]}};
get_form(_Host, ?NS_ADMINL(<<"user-stats">>), Lang) ->
{result,
- [#xmlel{name = <<"x">>,
- attrs = [{<<"xmlns">>, ?NS_XDATA}],
- children =
- [?HFIELD(),
- #xmlel{name = <<"title">>, attrs = [],
- children =
- [{xmlcdata, ?T(Lang, <<"Get User Statistics">>)}]},
- #xmlel{name = <<"field">>,
- attrs =
- [{<<"type">>, <<"jid-single">>},
- {<<"label">>, ?T(Lang, <<"Jabber ID">>)},
- {<<"var">>, <<"accountjid">>}],
- children =
- [#xmlel{name = <<"required">>, attrs = [],
- children = []}]}]}]};
+ #xdata{title = ?T(Lang, <<"Get User Statistics">>),
+ type = form,
+ fields = [?HFIELD(),
+ #xdata_field{type = 'jid-single',
+ label = ?T(Lang, <<"Jabber ID">>),
+ var = <<"accountjid">>,
+ required = true}]}};
get_form(Host,
?NS_ADMINL(<<"get-registered-users-num">>), Lang) ->
Num = list_to_binary(
io_lib:format("~p",
[ejabberd_auth:get_vh_registered_users_number(Host)])),
{result, completed,
- [#xmlel{name = <<"x">>,
- attrs = [{<<"xmlns">>, ?NS_XDATA}],
- children =
- [?HFIELD(),
- #xmlel{name = <<"field">>,
- attrs =
- [{<<"type">>, <<"text-single">>},
- {<<"label">>,
- ?T(Lang, <<"Number of registered users">>)},
- {<<"var">>, <<"registeredusersnum">>}],
- children =
- [#xmlel{name = <<"value">>, attrs = [],
- children = [{xmlcdata, Num}]}]}]}]};
+ #xdata{type = form,
+ fields = [?HFIELD(),
+ #xdata_field{type = 'text-single',
+ label = ?T(Lang, <<"Number of registered users">>),
+ var = <<"registeredusersnum">>,
+ values = [Num]}]}};
get_form(Host, ?NS_ADMINL(<<"get-online-users-num">>),
Lang) ->
Num = list_to_binary(
io_lib:format("~p",
[length(ejabberd_sm:get_vh_session_list(Host))])),
{result, completed,
- [#xmlel{name = <<"x">>,
- attrs = [{<<"xmlns">>, ?NS_XDATA}],
- children =
- [?HFIELD(),
- #xmlel{name = <<"field">>,
- attrs =
- [{<<"type">>, <<"text-single">>},
- {<<"label">>,
- ?T(Lang, <<"Number of online users">>)},
- {<<"var">>, <<"onlineusersnum">>}],
- children =
- [#xmlel{name = <<"value">>, attrs = [],
- children = [{xmlcdata, Num}]}]}]}]};
+ #xdata{type = form,
+ fields = [?HFIELD(),
+ #xdata_field{type = 'text-single',
+ label = ?T(Lang, <<"Number of online users">>),
+ var = <<"onlineusersnum">>,
+ values = [Num]}]}};
get_form(_Host, _, _Lang) ->
- {error, ?ERR_SERVICE_UNAVAILABLE}.
+ {error, xmpp:err_service_unavailable()}.
set_form(_From, _Host,
[<<"running nodes">>, ENode, <<"DB">>], Lang, XData) ->
case search_running_node(ENode) of
false ->
Txt = <<"No running node found">>,
- {error, ?ERRT_ITEM_NOT_FOUND(Lang, Txt)};
+ {error, xmpp:err_item_not_found(Txt, Lang)};
Node ->
- lists:foreach(fun ({SVar, SVals}) ->
- Table = jlib:binary_to_atom(SVar),
- Type = case SVals of
- [<<"unknown">>] -> unknown;
- [<<"ram_copies">>] -> ram_copies;
- [<<"disc_copies">>] -> disc_copies;
- [<<"disc_only_copies">>] ->
- disc_only_copies;
- _ -> false
- end,
- if Type == false -> ok;
- Type == unknown ->
- mnesia:del_table_copy(Table, Node);
- true ->
- case mnesia:add_table_copy(Table, Node,
- Type)
- of
- {aborted, _} ->
- mnesia:change_table_copy_type(Table,
- Node,
- Type);
- _ -> ok
- end
- end
- end,
- XData),
- {result, []}
+ lists:foreach(
+ fun(#xdata_field{var = SVar, values = SVals}) ->
+ Table = jlib:binary_to_atom(SVar),
+ Type = case SVals of
+ [<<"unknown">>] -> unknown;
+ [<<"ram_copies">>] -> ram_copies;
+ [<<"disc_copies">>] -> disc_copies;
+ [<<"disc_only_copies">>] -> disc_only_copies;
+ _ -> false
+ end,
+ if Type == false -> ok;
+ Type == unknown ->
+ mnesia:del_table_copy(Table, Node);
+ true ->
+ case mnesia:add_table_copy(Table, Node, Type) of
+ {aborted, _} ->
+ mnesia:change_table_copy_type(
+ Table, Node, Type);
+ _ -> ok
+ end
+ end
+ end, XData#xdata.fields),
+ {result, undefined}
end;
set_form(_From, Host,
[<<"running nodes">>, ENode, <<"modules">>, <<"stop">>],
case search_running_node(ENode) of
false ->
Txt = <<"No running node found">>,
- {error, ?ERRT_ITEM_NOT_FOUND(Lang, Txt)};
+ {error, xmpp:err_item_not_found(Txt, Lang)};
Node ->
- lists:foreach(fun ({Var, Vals}) ->
- case Vals of
- [<<"1">>] ->
- Module = jlib:binary_to_atom(Var),
- ejabberd_cluster:call(Node, gen_mod, stop_module,
- [Host, Module]);
- _ -> ok
- end
- end,
- XData),
- {result, []}
+ lists:foreach(
+ fun(#xdata_field{var = Var, values = Vals}) ->
+ case Vals of
+ [<<"1">>] ->
+ Module = jlib:binary_to_atom(Var),
+ ejabberd_cluster:call(Node, gen_mod, stop_module,
+ [Host, Module]);
+ _ -> ok
+ end
+ end, XData#xdata.fields),
+ {result, undefined}
end;
set_form(_From, Host,
[<<"running nodes">>, ENode, <<"modules">>,
<<"start">>],
Lang, XData) ->
case search_running_node(ENode) of
- false ->
- Txt = <<"No running node found">>,
- {error, ?ERRT_ITEM_NOT_FOUND(Lang, Txt)};
- Node ->
- case lists:keysearch(<<"modules">>, 1, XData) of
- false ->
- Txt = <<"No 'modules' found in data form">>,
- {error, ?ERRT_BAD_REQUEST(Lang, Txt)};
- {value, {_, Strings}} ->
- String = lists:foldl(fun (S, Res) ->
- <<Res/binary, S/binary, "\n">>
- end,
- <<"">>, Strings),
- case erl_scan:string(binary_to_list(String)) of
- {ok, Tokens, _} ->
- case erl_parse:parse_term(Tokens) of
- {ok, Modules} ->
- lists:foreach(fun ({Module, Args}) ->
- ejabberd_cluster:call(Node, gen_mod,
- start_module,
- [Host, Module, Args])
- end,
- Modules),
- {result, []};
- _ -> {error, ?ERRT_BAD_REQUEST(Lang, <<"Parse failed">>)}
- end;
- _ -> {error, ?ERRT_BAD_REQUEST(Lang, <<"Scan failed">>)}
- end
- end
+ false ->
+ Txt = <<"No running node found">>,
+ {error, xmpp:err_item_not_found(Txt, Lang)};
+ Node ->
+ case xmpp_util:get_xdata_values(<<"modules">>, XData) of
+ [] ->
+ Txt = <<"No 'modules' found in data form">>,
+ {error, xmpp:err_bad_request(Txt, Lang)};
+ Strings ->
+ String = lists:foldl(fun (S, Res) ->
+ <<Res/binary, S/binary, "\n">>
+ end, <<"">>, Strings),
+ case erl_scan:string(binary_to_list(String)) of
+ {ok, Tokens, _} ->
+ case erl_parse:parse_term(Tokens) of
+ {ok, Modules} ->
+ lists:foreach(
+ fun ({Module, Args}) ->
+ ejabberd_cluster:call(
+ Node, gen_mod, start_module,
+ [Host, Module, Args])
+ end,
+ Modules),
+ {result, undefined};
+ _ ->
+ Txt = <<"Parse failed">>,
+ {error, xmpp:err_bad_request(Txt, Lang)}
+ end;
+ _ ->
+ Txt = <<"Scan failed">>,
+ {error, xmpp:err_bad_request(Txt, Lang)}
+ end
+ end
end;
set_form(_From, _Host,
[<<"running nodes">>, ENode, <<"backup">>,
<<"backup">>],
Lang, XData) ->
case search_running_node(ENode) of
- false ->
- Txt = <<"No running node found">>,
- {error, ?ERRT_ITEM_NOT_FOUND(Lang, Txt)};
- Node ->
- case lists:keysearch(<<"path">>, 1, XData) of
- false ->
- Txt = <<"No 'path' found in data form">>,
- {error, ?ERRT_BAD_REQUEST(Lang, Txt)};
- {value, {_, [String]}} ->
- case ejabberd_cluster:call(Node, mnesia, backup, [String]) of
- {badrpc, Reason} ->
- ?ERROR_MSG("RPC call mnesia:backup(~s) to node ~s "
- "failed: ~p", [String, Node, Reason]),
- {error, ?ERR_INTERNAL_SERVER_ERROR};
- {error, Reason} ->
- ?ERROR_MSG("RPC call mnesia:backup(~s) to node ~s "
- "failed: ~p", [String, Node, Reason]),
- {error, ?ERR_INTERNAL_SERVER_ERROR};
- _ -> {result, []}
- end;
- _ ->
- Txt = <<"Incorrect value of 'path' in data form">>,
- {error, ?ERRT_BAD_REQUEST(Lang, Txt)}
- end
+ false ->
+ Txt = <<"No running node found">>,
+ {error, xmpp:err_item_not_found(Txt, Lang)};
+ Node ->
+ case xmpp_util:get_xdata_values(<<"path">>, XData) of
+ [] ->
+ Txt = <<"No 'path' found in data form">>,
+ {error, xmpp:err_bad_request(Txt, Lang)};
+ [String] ->
+ case ejabberd_cluster:call(Node, mnesia, backup, [String]) of
+ {badrpc, Reason} ->
+ ?ERROR_MSG("RPC call mnesia:backup(~s) to node ~s "
+ "failed: ~p", [String, Node, Reason]),
+ {error, xmpp:err_internal_server_error()};
+ {error, Reason} ->
+ ?ERROR_MSG("RPC call mnesia:backup(~s) to node ~s "
+ "failed: ~p", [String, Node, Reason]),
+ {error, xmpp:err_internal_server_error()};
+ _ ->
+ {result, undefined}
+ end;
+ _ ->
+ Txt = <<"Incorrect value of 'path' in data form">>,
+ {error, xmpp:err_bad_request(Txt, Lang)}
+ end
end;
set_form(_From, _Host,
[<<"running nodes">>, ENode, <<"backup">>,
<<"restore">>],
Lang, XData) ->
case search_running_node(ENode) of
- false ->
- Txt = <<"No running node found">>,
- {error, ?ERRT_ITEM_NOT_FOUND(Lang, Txt)};
- Node ->
- case lists:keysearch(<<"path">>, 1, XData) of
- false ->
- Txt = <<"No 'path' found in data form">>,
- {error, ?ERRT_BAD_REQUEST(Lang, Txt)};
- {value, {_, [String]}} ->
- case ejabberd_cluster:call(Node, ejabberd_admin, restore, [String])
- of
- {badrpc, Reason} ->
- ?ERROR_MSG("RPC call ejabberd_admin:restore(~s) to node "
- "~s failed: ~p", [String, Node, Reason]),
- {error, ?ERR_INTERNAL_SERVER_ERROR};
- {error, Reason} ->
- ?ERROR_MSG("RPC call ejabberd_admin:restore(~s) to node "
- "~s failed: ~p", [String, Node, Reason]),
- {error, ?ERR_INTERNAL_SERVER_ERROR};
- _ -> {result, []}
- end;
- _ ->
- Txt = <<"Incorrect value of 'path' in data form">>,
- {error, ?ERRT_BAD_REQUEST(Lang, Txt)}
- end
+ false ->
+ Txt = <<"No running node found">>,
+ {error, xmpp:err_item_not_found(Txt, Lang)};
+ Node ->
+ case xmpp_util:get_xdata_values(<<"path">>, XData) of
+ [] ->
+ Txt = <<"No 'path' found in data form">>,
+ {error, xmpp:err_bad_request(Txt, Lang)};
+ [String] ->
+ case ejabberd_cluster:call(Node, ejabberd_admin,
+ restore, [String]) of
+ {badrpc, Reason} ->
+ ?ERROR_MSG("RPC call ejabberd_admin:restore(~s) to node "
+ "~s failed: ~p", [String, Node, Reason]),
+ {error, xmpp:err_internal_server_error()};
+ {error, Reason} ->
+ ?ERROR_MSG("RPC call ejabberd_admin:restore(~s) to node "
+ "~s failed: ~p", [String, Node, Reason]),
+ {error, xmpp:err_internal_server_error()};
+ _ ->
+ {result, undefined}
+ end;
+ _ ->
+ Txt = <<"Incorrect value of 'path' in data form">>,
+ {error, xmpp:err_bad_request(Txt, Lang)}
+ end
end;
set_form(_From, _Host,
[<<"running nodes">>, ENode, <<"backup">>,
<<"textfile">>],
Lang, XData) ->
case search_running_node(ENode) of
- false ->
- Txt = <<"No running node found">>,
- {error, ?ERRT_ITEM_NOT_FOUND(Lang, Txt)};
- Node ->
- case lists:keysearch(<<"path">>, 1, XData) of
- false ->
- Txt = <<"No 'path' found in data form">>,
- {error, ?ERRT_BAD_REQUEST(Lang, Txt)};
- {value, {_, [String]}} ->
- case ejabberd_cluster:call(Node, ejabberd_admin, dump_to_textfile,
- [String])
- of
- {badrpc, Reason} ->
- ?ERROR_MSG("RPC call ejabberd_admin:dump_to_textfile(~s) "
- "to node ~s failed: ~p", [String, Node, Reason]),
- {error, ?ERR_INTERNAL_SERVER_ERROR};
- {error, Reason} ->
- ?ERROR_MSG("RPC call ejabberd_admin:dump_to_textfile(~s) "
- "to node ~s failed: ~p", [String, Node, Reason]),
- {error, ?ERR_INTERNAL_SERVER_ERROR};
- _ -> {result, []}
- end;
- _ ->
- Txt = <<"Incorrect value of 'path' in data form">>,
- {error, ?ERRT_BAD_REQUEST(Lang, Txt)}
- end
+ false ->
+ Txt = <<"No running node found">>,
+ {error, xmpp:err_item_not_found(Txt, Lang)};
+ Node ->
+ case xmpp_util:get_xdata_values(<<"path">>, XData) of
+ [] ->
+ Txt = <<"No 'path' found in data form">>,
+ {error, xmpp:err_bad_request(Txt, Lang)};
+ [String] ->
+ case ejabberd_cluster:call(Node, ejabberd_admin,
+ dump_to_textfile, [String]) of
+ {badrpc, Reason} ->
+ ?ERROR_MSG("RPC call ejabberd_admin:dump_to_textfile(~s) "
+ "to node ~s failed: ~p", [String, Node, Reason]),
+ {error, xmpp:err_internal_server_error()};
+ {error, Reason} ->
+ ?ERROR_MSG("RPC call ejabberd_admin:dump_to_textfile(~s) "
+ "to node ~s failed: ~p", [String, Node, Reason]),
+ {error, xmpp:err_internal_server_error()};
+ _ ->
+ {result, undefined}
+ end;
+ _ ->
+ Txt = <<"Incorrect value of 'path' in data form">>,
+ {error, xmpp:err_bad_request(Txt, Lang)}
+ end
end;
set_form(_From, _Host,
[<<"running nodes">>, ENode, <<"import">>, <<"file">>],
Lang, XData) ->
case search_running_node(ENode) of
- false ->
- Txt = <<"No running node found">>,
- {error, ?ERRT_ITEM_NOT_FOUND(Lang, Txt)};
- Node ->
- case lists:keysearch(<<"path">>, 1, XData) of
- false ->
- Txt = <<"No 'path' found in data form">>,
- {error, ?ERRT_BAD_REQUEST(Lang, Txt)};
- {value, {_, [String]}} ->
- ejabberd_cluster:call(Node, jd2ejd, import_file, [String]),
- {result, []};
- _ ->
- Txt = <<"Incorrect value of 'path' in data form">>,
- {error, ?ERRT_BAD_REQUEST(Lang, Txt)}
- end
+ false ->
+ Txt = <<"No running node found">>,
+ {error, xmpp:err_item_not_found(Txt, Lang)};
+ Node ->
+ case xmpp_util:get_xdata_values(<<"path">>, XData) of
+ [] ->
+ Txt = <<"No 'path' found in data form">>,
+ {error, xmpp:err_bad_request(Txt, Lang)};
+ [String] ->
+ ejabberd_cluster:call(Node, jd2ejd, import_file, [String]),
+ {result, undefined};
+ _ ->
+ Txt = <<"Incorrect value of 'path' in data form">>,
+ {error, xmpp:err_bad_request(Txt, Lang)}
+ end
end;
set_form(_From, _Host,
[<<"running nodes">>, ENode, <<"import">>, <<"dir">>],
Lang, XData) ->
case search_running_node(ENode) of
- false ->
- Txt = <<"No running node found">>,
- {error, ?ERRT_ITEM_NOT_FOUND(Lang, Txt)};
- Node ->
- case lists:keysearch(<<"path">>, 1, XData) of
- false ->
- Txt = <<"No 'path' found in data form">>,
- {error, ?ERRT_BAD_REQUEST(Lang, Txt)};
- {value, {_, [String]}} ->
- ejabberd_cluster:call(Node, jd2ejd, import_dir, [String]),
- {result, []};
- _ ->
- Txt = <<"Incorrect value of 'path' in data form">>,
- {error, ?ERRT_BAD_REQUEST(Lang, Txt)}
- end
+ false ->
+ Txt = <<"No running node found">>,
+ {error, xmpp:err_item_not_found(Txt, Lang)};
+ Node ->
+ case xmpp_util:get_xdata_values(<<"path">>, XData) of
+ [] ->
+ Txt = <<"No 'path' found in data form">>,
+ {error, xmpp:err_bad_request(Txt, Lang)};
+ [String] ->
+ ejabberd_cluster:call(Node, jd2ejd, import_dir, [String]),
+ {result, undefined};
+ _ ->
+ Txt = <<"Incorrect value of 'path' in data form">>,
+ {error, xmpp:err_bad_request(Txt, Lang)}
+ end
end;
set_form(From, Host,
[<<"running nodes">>, ENode, <<"restart">>], _Lang,
stop_node(From, Host, ENode, stop, XData);
set_form(_From, Host, [<<"config">>, <<"acls">>], Lang,
XData) ->
- case lists:keysearch(<<"acls">>, 1, XData) of
- {value, {_, Strings}} ->
- String = lists:foldl(fun (S, Res) ->
- <<Res/binary, S/binary, "\n">>
- end,
- <<"">>, Strings),
- case erl_scan:string(binary_to_list(String)) of
- {ok, Tokens, _} ->
- case erl_parse:parse_term(Tokens) of
- {ok, ACLs} ->
- acl:add_list(Host, ACLs, true),
- {result, []};
- _ -> {error, ?ERRT_BAD_REQUEST(Lang, <<"Parse failed">>)}
- end;
- _ -> {error, ?ERRT_BAD_REQUEST(Lang, <<"Scan failed">>)}
- end;
- _ ->
- Txt = <<"No 'acls' found in data form">>,
- {error, ?ERRT_BAD_REQUEST(Lang, Txt)}
+ case xmpp_util:get_xdata_values(<<"acls">>, XData) of
+ [] ->
+ Txt = <<"No 'acls' found in data form">>,
+ {error, xmpp:err_bad_request(Txt, Lang)};
+ Strings ->
+ String = lists:foldl(fun (S, Res) ->
+ <<Res/binary, S/binary, "\n">>
+ end, <<"">>, Strings),
+ case erl_scan:string(binary_to_list(String)) of
+ {ok, Tokens, _} ->
+ case erl_parse:parse_term(Tokens) of
+ {ok, ACLs} ->
+ acl:add_list(Host, ACLs, true),
+ {result, undefined};
+ _ ->
+ Txt = <<"Parse failed">>,
+ {error, xmpp:err_bad_request(Txt, Lang)}
+ end;
+ _ ->
+ {error, xmpp:err_bad_request(<<"Scan failed">>, Lang)}
+ end
end;
set_form(_From, Host, [<<"config">>, <<"access">>],
Lang, XData) ->
- SetAccess = fun (Rs) ->
- mnesia:transaction(fun () ->
- Os = mnesia:select(access,
- [{{access,
- {'$1',
- '$2'},
- '$3'},
- [{'==',
- '$2',
- Host}],
- ['$_']}]),
- lists:foreach(fun (O) ->
- mnesia:delete_object(O)
- end,
- Os),
- lists:foreach(fun ({access,
- Name,
- Rules}) ->
- mnesia:write({access,
- {Name,
- Host},
- Rules})
- end,
- Rs)
- end)
- end,
- case lists:keysearch(<<"access">>, 1, XData) of
- {value, {_, Strings}} ->
- String = lists:foldl(fun (S, Res) ->
- <<Res/binary, S/binary, "\n">>
- end,
- <<"">>, Strings),
- case erl_scan:string(binary_to_list(String)) of
- {ok, Tokens, _} ->
- case erl_parse:parse_term(Tokens) of
- {ok, Rs} ->
- case SetAccess(Rs) of
- {atomic, _} -> {result, []};
- _ -> {error, ?ERR_BAD_REQUEST}
- end;
- _ -> {error, ?ERRT_BAD_REQUEST(Lang, <<"Parse failed">>)}
- end;
- _ -> {error, ?ERRT_BAD_REQUEST(Lang, <<"Scan failed">>)}
- end;
- _ ->
- Txt = <<"No 'access' found in data form">>,
- {error, ?ERRT_BAD_REQUEST(Lang, Txt)}
+ SetAccess =
+ fun(Rs) ->
+ mnesia:transaction(
+ fun () ->
+ Os = mnesia:select(
+ access,
+ ets:fun2ms(
+ fun({access, {_, H}, _} = O) when H == Host ->
+ O
+ end)),
+ lists:foreach(fun mnesia:delete_object/1, Os),
+ lists:foreach(
+ fun({access, Name, Rules}) ->
+ mnesia:write({access, {Name, Host}, Rules})
+ end, Rs)
+ end)
+ end,
+ case xmpp_util:get_xdata_values(<<"access">>, XData) of
+ [] ->
+ Txt = <<"No 'access' found in data form">>,
+ {error, xmpp:err_bad_request(Txt, Lang)};
+ Strings ->
+ String = lists:foldl(fun (S, Res) ->
+ <<Res/binary, S/binary, "\n">>
+ end, <<"">>, Strings),
+ case erl_scan:string(binary_to_list(String)) of
+ {ok, Tokens, _} ->
+ case erl_parse:parse_term(Tokens) of
+ {ok, Rs} ->
+ case SetAccess(Rs) of
+ {atomic, _} ->
+ {result, undefined};
+ _ ->
+ {error, xmpp:err_bad_request()}
+ end;
+ _ ->
+ Txt = <<"Parse failed">>,
+ {error, xmpp:err_bad_request(Txt, Lang)}
+ end;
+ _ ->
+ {error, xmpp:err_bad_request(<<"Scan failed">>, Lang)}
+ end
end;
set_form(From, Host, ?NS_ADMINL(<<"add-user">>), _Lang,
XData) ->
true = Server == Host orelse
get_permission_level(From) == global,
ejabberd_auth:try_register(User, Server, Password),
- {result, []};
+ {result, undefined};
set_form(From, Host, ?NS_ADMINL(<<"delete-user">>),
_Lang, XData) ->
AccountStringList = get_values(<<"accountjids">>,
AccountStringList),
[ejabberd_auth:remove_user(User, Server)
|| {User, Server} <- ASL2],
- {result, []};
+ {result, undefined};
set_form(From, Host, ?NS_ADMINL(<<"end-user-session">>),
Lang, XData) ->
AccountString = get_value(<<"accountjid">>, XData),
LServer = JID#jid.lserver,
true = LServer == Host orelse
get_permission_level(From) == global,
- Xmlelement = ?SERRT_POLICY_VIOLATION(Lang, <<"has been kicked">>),
+ Xmlelement = xmpp:serr_policy_violation(<<"has been kicked">>, Lang),
case JID#jid.lresource of
<<>> ->
SIDs = mnesia:dirty_select(session,
[{{'$1', '$2'}}]}]),
Pid ! {kick, kicked_by_admin, Xmlelement}
end,
- {result, []};
+ {result, undefined};
set_form(From, Host,
?NS_ADMINL(<<"get-user-password">>), Lang, XData) ->
AccountString = get_value(<<"accountjid">>, XData),
Password = ejabberd_auth:get_password(User, Server),
true = is_binary(Password),
{result,
- [#xmlel{name = <<"x">>,
- attrs = [{<<"xmlns">>, ?NS_XDATA}],
- children =
- [?HFIELD(),
- ?XFIELD(<<"jid-single">>, <<"Jabber ID">>,
- <<"accountjid">>, AccountString),
- ?XFIELD(<<"text-single">>, <<"Password">>,
- <<"password">>, Password)]}]};
+ #xdata{type = form,
+ fields = [?HFIELD(),
+ ?XFIELD('jid-single', <<"Jabber ID">>,
+ <<"accountjid">>, AccountString),
+ ?XFIELD('text-single', <<"Password">>,
+ <<"password">>, Password)]}};
set_form(From, Host,
?NS_ADMINL(<<"change-user-password">>), _Lang, XData) ->
AccountString = get_value(<<"accountjid">>, XData),
get_permission_level(From) == global,
true = ejabberd_auth:is_user_exists(User, Server),
ejabberd_auth:set_password(User, Server, Password),
- {result, []};
+ {result, undefined};
set_form(From, Host,
?NS_ADMINL(<<"get-user-lastlogin">>), Lang, XData) ->
AccountString = get_value(<<"accountjid">>, XData),
_ -> ?T(Lang, <<"Online">>)
end,
{result,
- [#xmlel{name = <<"x">>,
- attrs =
- [{<<"xmlns">>, ?NS_XDATA}, {<<"type">>, <<"result">>}],
- children =
- [?HFIELD(),
- ?XFIELD(<<"jid-single">>, <<"Jabber ID">>,
- <<"accountjid">>, AccountString),
- ?XFIELD(<<"text-single">>, <<"Last login">>,
- <<"lastlogin">>, FLast)]}]};
+ #xdata{type = form,
+ fields = [?HFIELD(),
+ ?XFIELD('jid-single', <<"Jabber ID">>,
+ <<"accountjid">>, AccountString),
+ ?XFIELD('text-single', <<"Last login">>,
+ <<"lastlogin">>, FLast)]}};
set_form(From, Host, ?NS_ADMINL(<<"user-stats">>), Lang,
XData) ->
AccountString = get_value(<<"accountjid">>, XData),
[{User, Server}]),
Rostersize = jlib:integer_to_binary(erlang:length(Items)),
{result,
- [#xmlel{name = <<"x">>,
- attrs = [{<<"xmlns">>, ?NS_XDATA}],
- children =
- [?HFIELD(),
- ?XFIELD(<<"jid-single">>, <<"Jabber ID">>,
- <<"accountjid">>, AccountString),
- ?XFIELD(<<"text-single">>, <<"Roster size">>,
- <<"rostersize">>, Rostersize),
- ?XMFIELD(<<"text-multi">>, <<"IP addresses">>,
- <<"ipaddresses">>, IPs),
- ?XMFIELD(<<"text-multi">>, <<"Resources">>,
- <<"onlineresources">>, Resources)]}]};
+ #xdata{type = form,
+ fields = [?HFIELD(),
+ ?XFIELD('jid-single', <<"Jabber ID">>,
+ <<"accountjid">>, AccountString),
+ ?XFIELD('text-single', <<"Roster size">>,
+ <<"rostersize">>, Rostersize),
+ ?XMFIELD('text-multi', <<"IP addresses">>,
+ <<"ipaddresses">>, IPs),
+ ?XMFIELD('text-multi', <<"Resources">>,
+ <<"onlineresources">>, Resources)]}};
set_form(_From, _Host, _, _Lang, _XData) ->
- {error, ?ERR_SERVICE_UNAVAILABLE}.
+ {error, xmpp:err_service_unavailable()}.
get_value(Field, XData) -> hd(get_values(Field, XData)).
get_values(Field, XData) ->
- {value, {_, ValueList}} = lists:keysearch(Field, 1,
- XData),
- ValueList.
+ [_|_] = Values = xmpp_util:get_xdata_values(Field, XData),
+ Values.
search_running_node(SNode) ->
search_running_node(SNode,
end.
stop_node(From, Host, ENode, Action, XData) ->
- Delay = jlib:binary_to_integer(get_value(<<"delay">>,
- XData)),
+ Delay = jlib:binary_to_integer(get_value(<<"delay">>, XData)),
Subject = case get_value(<<"subject">>, XData) of
- <<"">> -> [];
- S ->
- [#xmlel{name = <<"field">>,
- attrs = [{<<"var">>, <<"subject">>}],
- children =
- [#xmlel{name = <<"value">>, attrs = [],
- children = [{xmlcdata, S}]}]}]
+ <<"">> ->
+ [];
+ S ->
+ [#xdata_field{var = <<"subject">>, values = [S]}]
end,
- Announcement = case get_values(<<"announcement">>,
- XData)
- of
- [] -> [];
- As ->
- [#xmlel{name = <<"field">>,
- attrs = [{<<"var">>, <<"body">>}],
- children =
- [#xmlel{name = <<"value">>, attrs = [],
- children = [{xmlcdata, Line}]}
- || Line <- As]}]
+ Announcement = case get_values(<<"announcement">>, XData) of
+ [] ->
+ [];
+ As ->
+ [#xdata_field{var = <<"body">>, values = As}]
end,
case Subject ++ Announcement of
- [] -> ok;
- SubEls ->
- Request = #adhoc_request{node =
- ?NS_ADMINX(<<"announce-allhosts">>),
- action = <<"complete">>,
- xdata =
- #xmlel{name = <<"x">>,
- attrs =
- [{<<"xmlns">>,
- ?NS_XDATA},
- {<<"type">>, <<"submit">>}],
- children = SubEls},
- others =
- [#xmlel{name = <<"x">>,
- attrs =
- [{<<"xmlns">>,
- ?NS_XDATA},
- {<<"type">>, <<"submit">>}],
- children = SubEls}]},
- To = jid:make(<<"">>, Host, <<"">>),
- mod_announce:announce_commands(empty, From, To, Request)
+ [] ->
+ ok;
+ Fields ->
+ Request = #adhoc_command{node = ?NS_ADMINX(<<"announce-allhosts">>),
+ action = complete,
+ xdata = #xdata{type = submit,
+ fields = Fields}},
+ To = jid:make(Host),
+ mod_announce:announce_commands(empty, From, To, Request)
end,
Time = timer:seconds(Delay),
Node = jlib:binary_to_atom(ENode),
- {ok, _} = timer:apply_after(Time, rpc, call,
- [Node, init, Action, []]),
- {result, []}.
+ {ok, _} = timer:apply_after(Time, rpc, call, [Node, init, Action, []]),
+ {result, undefined}.
get_last_info(User, Server) ->
case gen_mod:is_loaded(Server, mod_last) of
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
adhoc_sm_commands(_Acc, From,
- #jid{user = User, server = Server, lserver = LServer} =
- _To,
- #adhoc_request{lang = Lang, node = <<"config">>,
- action = Action, xdata = XData} =
- Request) ->
+ #jid{user = User, server = Server, lserver = LServer},
+ #adhoc_command{lang = Lang, node = <<"config">>,
+ action = Action, xdata = XData} = Request) ->
case acl:match_rule(LServer, configure, From) of
- deny -> {error, ?ERRT_FORBIDDEN(Lang, <<"Denied by ACL">>)};
- allow ->
- ActionIsExecute = lists:member(Action,
- [<<"">>, <<"execute">>,
- <<"complete">>]),
- if Action == <<"cancel">> ->
- adhoc:produce_response(Request,
- #adhoc_response{status = canceled});
- XData == false, ActionIsExecute ->
- case get_sm_form(User, Server, <<"config">>, Lang) of
- {result, Form} ->
- adhoc:produce_response(Request,
- #adhoc_response{status =
- executing,
- elements = Form});
- {error, Error} -> {error, Error}
- end;
- XData /= false, ActionIsExecute ->
- case jlib:parse_xdata_submit(XData) of
- invalid ->
- Txt = <<"Incorrect data form">>,
- {error, ?ERRT_BAD_REQUEST(Lang, Txt)};
- Fields ->
- set_sm_form(User, Server, <<"config">>, Request, Fields)
- end;
- true ->
- Txt = <<"Incorrect action or data form">>,
- {error, ?ERRT_BAD_REQUEST(Lang, Txt)}
- end
+ deny ->
+ {error, xmpp:err_forbidden(<<"Denied by ACL">>, Lang)};
+ allow ->
+ ActionIsExecute = Action == execute orelse Action == complete,
+ if Action == cancel ->
+ xmpp_util:make_adhoc_response(
+ Request, #adhoc_command{status = canceled});
+ XData == undefined, ActionIsExecute ->
+ case get_sm_form(User, Server, <<"config">>, Lang) of
+ {result, Form} ->
+ xmpp_util:make_adhoc_response(
+ Request, #adhoc_command{status = executing,
+ xdata = Form});
+ {error, Error} ->
+ {error, Error}
+ end;
+ XData /= undefined, ActionIsExecute ->
+ set_sm_form(User, Server, <<"config">>, Request);
+ true ->
+ Txt = <<"Unexpected action">>,
+ {error, xmpp:err_bad_request(Txt, Lang)}
+ end
end;
adhoc_sm_commands(Acc, _From, _To, _Request) -> Acc.
get_sm_form(User, Server, <<"config">>, Lang) ->
{result,
- [#xmlel{name = <<"x">>,
- attrs = [{<<"xmlns">>, ?NS_XDATA}],
- children =
- [?HFIELD(),
- #xmlel{name = <<"title">>, attrs = [],
- children =
- [{xmlcdata,
- <<(?T(Lang, <<"Administration of ">>))/binary,
- User/binary>>}]},
- #xmlel{name = <<"field">>,
- attrs =
- [{<<"type">>, <<"list-single">>},
- {<<"label">>, ?T(Lang, <<"Action on user">>)},
- {<<"var">>, <<"action">>}],
- children =
- [#xmlel{name = <<"value">>, attrs = [],
- children = [{xmlcdata, <<"edit">>}]},
- #xmlel{name = <<"option">>,
- attrs =
- [{<<"label">>,
- ?T(Lang, <<"Edit Properties">>)}],
- children =
- [#xmlel{name = <<"value">>, attrs = [],
- children =
- [{xmlcdata,
- <<"edit">>}]}]},
- #xmlel{name = <<"option">>,
- attrs =
- [{<<"label">>,
- ?T(Lang, <<"Remove User">>)}],
- children =
- [#xmlel{name = <<"value">>, attrs = [],
- children =
- [{xmlcdata,
- <<"remove">>}]}]}]},
- ?XFIELD(<<"text-private">>, <<"Password">>,
- <<"password">>,
- (ejabberd_auth:get_password_s(User, Server)))]}]};
+ #xdata{type = form,
+ title = <<(?T(Lang, <<"Administration of ">>))/binary, User/binary>>,
+ fields =
+ [?HFIELD(),
+ #xdata_field{
+ type = 'list-single',
+ label = ?T(Lang, <<"Action on user">>),
+ var = <<"action">>,
+ values = [<<"edit">>],
+ options = [#xdata_option{
+ label = ?T(Lang, <<"Edit Properties">>),
+ value = <<"edit">>},
+ #xdata_option{
+ label = ?T(Lang, <<"Remove User">>),
+ value = <<"remove">>}]},
+ ?XFIELD('text-private', <<"Password">>,
+ <<"password">>,
+ ejabberd_auth:get_password_s(User, Server))]}};
get_sm_form(_User, _Server, _Node, _Lang) ->
- {error, ?ERR_SERVICE_UNAVAILABLE}.
+ {error, xmpp:err_service_unavailable()}.
set_sm_form(User, Server, <<"config">>,
- #adhoc_request{lang = Lang, node = Node,
- sessionid = SessionID},
- XData) ->
- Response = #adhoc_response{lang = Lang, node = Node,
- sessionid = SessionID, status = completed},
- case lists:keysearch(<<"action">>, 1, XData) of
- {value, {_, [<<"edit">>]}} ->
- case lists:keysearch(<<"password">>, 1, XData) of
- {value, {_, [Password]}} ->
- ejabberd_auth:set_password(User, Server, Password),
- adhoc:produce_response(Response);
- _ ->
- Txt = <<"No 'password' found in data form">>,
- {error, ?ERRT_NOT_ACCEPTABLE(Lang, Txt)}
- end;
- {value, {_, [<<"remove">>]}} ->
- catch ejabberd_auth:remove_user(User, Server),
- adhoc:produce_response(Response);
- _ ->
- Txt = <<"Incorrect value of 'action' in data form">>,
- {error, ?ERRT_NOT_ACCEPTABLE(Lang, Txt)}
+ #adhoc_command{lang = Lang, node = Node,
+ sid = SessionID, xdata = XData}) ->
+ Response = #adhoc_command{lang = Lang, node = Node,
+ sid = SessionID, status = completed},
+ case xmpp_util:get_xdata_values(<<"action">>, XData) of
+ [<<"edit">>] ->
+ case xmpp_util:get_xdata_values(<<"password">>, XData) of
+ [Password] ->
+ ejabberd_auth:set_password(User, Server, Password),
+ xmpp_util:make_adhoc_response(Response);
+ _ ->
+ Txt = <<"No 'password' found in data form">>,
+ {error, xmpp:err_not_acceptable(Txt, Lang)}
+ end;
+ [<<"remove">>] ->
+ catch ejabberd_auth:remove_user(User, Server),
+ xmpp_util:make_adhoc_response(Response);
+ _ ->
+ Txt = <<"Incorrect value of 'action' in data form">>,
+ {error, xmpp:err_not_acceptable(Txt, Lang)}
end;
-set_sm_form(_User, _Server, _Node, _Request, _Fields) ->
- {error, ?ERR_SERVICE_UNAVAILABLE}.
+set_sm_form(_User, _Server, _Node, _Request) ->
+ {error, xmpp:err_service_unavailable()}.
mod_opt_type(_) -> [].