%%% Id : $Id$
%%%----------------------------------------------------------------------
+%%% Implements a small subset of XEP-0133: Service Administration Version 1.1 (2005-08-19)
+
-module(mod_announce).
-author('alexey@sevcom.net').
-define(PROCNAME, ejabberd_announce).
+-define(NS_ADMINL(Sub), ["http:","jabber.org","protocol","admin", Sub]).
+tokenize(Node) -> string:tokens(Node, "/#").
+
start(Host, _Opts) ->
mnesia:create_table(motd, [{disc_copies, [node()]},
{attributes, record_info(fields, motd)}]),
exit(whereis(Proc), stop),
{wait, Proc}.
-% Announcing via messages to a custom resource
+%% Announcing via messages to a custom resource
announce(From, To, Packet) ->
case To of
#jid{luser = "", lresource = Res} ->
ok
end.
-%-------------------------------------------------------------------------
-% Announcing via ad-hoc commands
+%%-------------------------------------------------------------------------
+%% Announcing via ad-hoc commands
-define(INFO_COMMAND(Lang, Node),
[{xmlelement, "identity",
[{"category", "automation"},
{"name", get_title(Lang, Node)}], []}]).
disco_identity(Acc, _From, _To, Node, Lang) ->
- case Node of
- "announce/all" ->
+ LNode = tokenize(Node),
+ case LNode of
+ ?NS_ADMINL("announce-all") ->
?INFO_COMMAND(Lang, Node);
- "announce/all-hosts/all" ->
+ ?NS_ADMINL("announce-all-allhosts") ->
?INFO_COMMAND(Lang, Node);
- "announce/online" ->
+ ?NS_ADMINL("announce") ->
?INFO_COMMAND(Lang, Node);
- "announce/all-hosts/online" ->
+ ?NS_ADMINL("announce-online-allhosts") ->
?INFO_COMMAND(Lang, Node);
- "announce/motd" ->
+ ?NS_ADMINL("set-motd") ->
?INFO_COMMAND(Lang, Node);
- "announce/all-hosts/motd" ->
+ ?NS_ADMINL("motd-allhosts") ->
?INFO_COMMAND(Lang, Node);
- "announce/motd/delete" ->
+ ?NS_ADMINL("delete-motd") ->
?INFO_COMMAND(Lang, Node);
- "announce/all-hosts/motd/delete" ->
+ ?NS_ADMINL("delete-motd-allhosts") ->
?INFO_COMMAND(Lang, Node);
- "announce/motd/update" ->
+ ?NS_ADMINL("edit-motd") ->
?INFO_COMMAND(Lang, Node);
- "announce/all-hosts/motd/update" ->
+ ?NS_ADMINL("edit-motd-allhosts") ->
?INFO_COMMAND(Lang, Node);
_ ->
Acc
end.
-%-------------------------------------------------------------------------
+%%-------------------------------------------------------------------------
-define(INFO_RESULT(Allow, Feats),
- case Allow of
- deny ->
- {error, ?ERR_FORBIDDEN};
- allow ->
- {result, Feats}
- end).
+ case Allow of
+ deny ->
+ {error, ?ERR_FORBIDDEN};
+ allow ->
+ {result, Feats}
+ end).
disco_features(Acc, From, #jid{lserver = LServer} = _To,
"announce", _Lang) ->
disco_features(Acc, From, #jid{lserver = LServer} = _To,
Node, _Lang)
- when (Node == "announce/all-hosts/online")
- or (Node == "announce/all-hosts/all")
- or (Node == "announce/all-hosts/motd")
- or (Node == "announce/all-hosts/motd/update")
- or (Node == "announce/all-hosts/motd/delete") ->
+ when (Node == [?NS_ADMIN | "#announce-online-allhosts"])
+or (Node == [?NS_ADMIN | "#announce-all-allhosts"])
+or (Node == [?NS_ADMIN | "#motd-allhosts"])
+or (Node == [?NS_ADMIN | "#edit-motd-allhosts"])
+or (Node == [?NS_ADMIN | "#delete-motd-allhosts"]) ->
case gen_mod:is_loaded(LServer, mod_adhoc) of
false ->
Acc;
Access = gen_mod:get_module_opt(LServer, ?MODULE, access, none),
Allow = acl:match_rule(LServer, Access, From),
case Node of
- "announce/all" ->
+ ?NS_ADMIN ++ "#announce-all" ->
?INFO_RESULT(Allow, [?NS_COMMANDS]);
- "announce/online" ->
+ ?NS_ADMIN ++ "#announce" ->
?INFO_RESULT(Allow, [?NS_COMMANDS]);
- "announce/motd" ->
+ ?NS_ADMIN ++ "#set-motd" ->
?INFO_RESULT(Allow, [?NS_COMMANDS]);
- "announce/motd/delete" ->
+ ?NS_ADMIN ++ "#delete-motd" ->
?INFO_RESULT(Allow, [?NS_COMMANDS]);
- "announce/motd/update" ->
+ ?NS_ADMIN ++ "#edit-motd" ->
?INFO_RESULT(Allow, [?NS_COMMANDS]);
_ ->
Acc
end
end.
-%-------------------------------------------------------------------------
+%%-------------------------------------------------------------------------
-define(NODE_TO_ITEM(Lang, Server, Node),
{xmlelement, "item",
[]}).
-define(ITEMS_RESULT(Allow, Items),
- case Allow of
- deny ->
- {error, ?ERR_FORBIDDEN};
- allow ->
- {result, Items}
- end).
+ case Allow of
+ deny ->
+ {error, ?ERR_FORBIDDEN};
+ allow ->
+ {result, Items}
+ end).
disco_items(Acc, From, #jid{lserver = LServer, server = Server} = _To,
"", Lang) ->
end;
disco_items(Acc, From, #jid{lserver = LServer} = _To, Node, _Lang)
- when (Node == "announce/all-hosts/online")
- or (Node == "announce/all-hosts/all")
- or (Node == "announce/all-hosts/motd")
- or (Node == "announce/all-hosts/motd/update")
- or (Node == "announce/all-hosts/motd/delete") ->
+ when (Node == [?NS_ADMIN | "#announce-online-allhosts"])
+or (Node == [?NS_ADMIN | "#announce-all-allhosts"])
+or (Node == [?NS_ADMIN | "#motd-allhosts"])
+or (Node == [?NS_ADMIN | "#edit-motd-allhosts"])
+or (Node == [?NS_ADMIN | "#delete-motd-allhosts"]) ->
case gen_mod:is_loaded(LServer, mod_adhoc) of
false ->
Acc;
Access = gen_mod:get_module_opt(LServer, ?MODULE, access, none),
Allow = acl:match_rule(LServer, Access, From),
case Node of
- "announce/all" ->
+ ?NS_ADMIN ++ "#announce-all" ->
?ITEMS_RESULT(Allow, []);
- "announce/online" ->
+ ?NS_ADMIN ++ "#announce" ->
?ITEMS_RESULT(Allow, []);
- "announce/motd" ->
+ ?NS_ADMIN ++ "#set-motd" ->
?ITEMS_RESULT(Allow, []);
- "announce/motd/delete" ->
+ ?NS_ADMIN ++ "#delete-motd" ->
?ITEMS_RESULT(Allow, []);
- "announce/motd/update" ->
+ ?NS_ADMIN ++ "#edit-motd" ->
?ITEMS_RESULT(Allow, []);
_ ->
Acc
end
end.
-%-------------------------------------------------------------------------
+%%-------------------------------------------------------------------------
announce_items(Acc, From, #jid{lserver = LServer, server = Server} = _To, Lang) ->
Access1 = gen_mod:get_module_opt(LServer, ?MODULE, access, none),
Nodes1 = case acl:match_rule(LServer, Access1, From) of
allow ->
- [?NODE_TO_ITEM(Lang, Server, "announce/all"),
- ?NODE_TO_ITEM(Lang, Server, "announce/online"),
- ?NODE_TO_ITEM(Lang, Server, "announce/motd"),
- ?NODE_TO_ITEM(Lang, Server, "announce/motd/delete"),
- ?NODE_TO_ITEM(Lang, Server, "announce/motd/update")];
+ [?NODE_TO_ITEM(Lang, Server, ?NS_ADMIN ++ "#announce-all"),
+ ?NODE_TO_ITEM(Lang, Server, ?NS_ADMIN ++ "#announce"),
+ ?NODE_TO_ITEM(Lang, Server, ?NS_ADMIN ++ "#set-motd"),
+ ?NODE_TO_ITEM(Lang, Server, ?NS_ADMIN ++ "#delete-motd"),
+ ?NODE_TO_ITEM(Lang, Server, ?NS_ADMIN ++ "#edit-motd")];
deny ->
[]
end,
Access2 = gen_mod:get_module_opt(global, ?MODULE, access, none),
Nodes2 = case acl:match_rule(global, Access2, From) of
allow ->
- [?NODE_TO_ITEM(Lang, Server, "announce/all-hosts/all"),
- ?NODE_TO_ITEM(Lang, Server, "announce/all-hosts/online"),
- ?NODE_TO_ITEM(Lang, Server, "announce/all-hosts/motd"),
- ?NODE_TO_ITEM(Lang, Server, "announce/all-hosts/motd/update"),
- ?NODE_TO_ITEM(Lang, Server, "announce/all-hosts/motd/delete")];
+ [?NODE_TO_ITEM(Lang, Server, ?NS_ADMIN ++ "#announce-all-allhosts"),
+ ?NODE_TO_ITEM(Lang, Server, ?NS_ADMIN ++ "#announce-online-allhosts"),
+ ?NODE_TO_ITEM(Lang, Server, ?NS_ADMIN ++ "#motd-allhosts"),
+ ?NODE_TO_ITEM(Lang, Server, ?NS_ADMIN ++ "#edit-motd-allhosts"),
+ ?NODE_TO_ITEM(Lang, Server, ?NS_ADMIN ++ "#delete-motd-allhosts")];
deny ->
[]
end,
{result, Items ++ Nodes1 ++ Nodes2}
end.
-%-------------------------------------------------------------------------
+%%-------------------------------------------------------------------------
--define(COMMANDS_RESULT(Allow, From, To, Request),
+commands_result(Allow, From, To, Request) ->
case Allow of
deny ->
{error, ?ERR_FORBIDDEN};
allow ->
announce_commands(From, To, Request)
- end).
-
-announce_commands(_Acc, From, To,
- #adhoc_request{
- node = Node} = Request)
- when (Node == "announce/all-hosts/online")
- or (Node == "announce/all-hosts/all")
- or (Node == "announce/all-hosts/motd")
- or (Node == "announce/all-hosts/motd/update")
- or (Node == "announce/all-hosts/motd/delete") ->
- Access = gen_mod:get_module_opt(global, ?MODULE, access, none),
- Allow = acl:match_rule(global, Access, From),
- ?COMMANDS_RESULT(Allow, From, To, Request);
+ end.
+
announce_commands(Acc, From, #jid{lserver = LServer} = To,
- #adhoc_request{node = Node} = Request) ->
- Access = gen_mod:get_module_opt(LServer, ?MODULE, access, none),
- Allow = acl:match_rule(LServer, Access, From),
- case Node of
- "announce/all" ->
- ?COMMANDS_RESULT(Allow, From, To, Request);
- "announce/online" ->
- ?COMMANDS_RESULT(Allow, From, To, Request);
- "announce/motd" ->
- ?COMMANDS_RESULT(Allow, From, To, Request);
- "announce/motd/delete" ->
- ?COMMANDS_RESULT(Allow, From, To, Request);
- "announce/motd/update" ->
- ?COMMANDS_RESULT(Allow, From, To, Request);
- _ ->
- Acc
+ #adhoc_request{ node = Node} = Request) ->
+ LNode = tokenize(Node),
+ F = fun() ->
+ Access = gen_mod:get_module_opt(global, ?MODULE, access, none),
+ Allow = acl:match_rule(global, Access, From),
+ commands_result(Allow, From, To, Request)
+ end,
+ R = case LNode of
+ ?NS_ADMINL("announce-online-allhosts") -> F();
+ ?NS_ADMINL("announce-all-allhosts") -> F();
+ ?NS_ADMINL("motd-allhosts") -> F();
+ ?NS_ADMINL("edit-motd-allhosts") -> F();
+ ?NS_ADMINL("delete-motd-allhosts") -> F();
+ _ ->
+ Access = gen_mod:get_module_opt(LServer, ?MODULE, access, none),
+ Allow = acl:match_rule(LServer, Access, From),
+ case LNode of
+ ?NS_ADMINL("announce-all") ->
+ commands_result(Allow, From, To, Request);
+ ?NS_ADMINL("announce") ->
+ commands_result(Allow, From, To, Request);
+ ?NS_ADMINL("set-motd") ->
+ commands_result(Allow, From, To, Request);
+ ?NS_ADMINL("delete-motd") ->
+ commands_result(Allow, From, To, Request);
+ ?NS_ADMINL("edit-motd") ->
+ commands_result(Allow, From, To, Request);
+ _ ->
+ unknown
+ end
+ end,
+ case R of
+ unknown -> Acc;
+ _ -> {stop, R}
end.
-%-------------------------------------------------------------------------
+%%-------------------------------------------------------------------------
announce_commands(From, To,
#adhoc_request{lang = Lang,
#adhoc_response{status = canceled});
XData == false, ActionIsExecute ->
%% User requests form
+ Elements = generate_adhoc_form(Lang, Node),
adhoc:produce_response(
Request,
#adhoc_response{status = executing,
- elements = [generate_adhoc_form(Lang, Node)]});
+ elements = [Elements]});
XData /= false, ActionIsExecute ->
%% User returns form.
case jlib:parse_xdata_submit(XData) of
{error, ?ERR_BAD_REQUEST}
end.
+-define(TVFIELD(Type, Var, Val),
+ {xmlelement, "field", [{"type", Type},
+ {"var", Var}],
+ [{xmlelement, "value", [], [{xmlcdata, Val}]}]}).
+-define(HFIELD(), ?TVFIELD("hidden", "FORM_TYPE", ?NS_ADMIN)).
+
generate_adhoc_form(Lang, Node) ->
+ LNode = tokenize(Node),
{xmlelement, "x",
[{"xmlns", ?NS_XDATA},
{"type", "form"}],
- [{xmlelement, "title", [], [{xmlcdata, get_title(Lang, Node)}]}]
+ [?HFIELD(),
+ {xmlelement, "title", [], [{xmlcdata, get_title(Lang, Node)}]}]
++
- if (Node == "announce/motd/delete")
- or (Node == "announce/all-hosts/motd/delete") ->
- [{xmlelement, "field",
+ if (LNode == ?NS_ADMINL("delete-motd"))
+ or (LNode == ?NS_ADMINL("delete-motd-allhosts")) ->
+ [{xmlelement, "field",
[{"var", "confirm"},
{"type", "boolean"},
{"label", translate:translate(Lang, "Really delete message of the day?")}],
[{xmlelement, "value",
- [],
- [{xmlcdata, "true"}]}]}];
- true ->
- [{xmlelement, "field",
- [{"var", "subject"},
- {"type", "text-single"},
- {"label", translate:translate(Lang, "Subject")}],
- []},
- {xmlelement, "field",
- [{"var", "body"},
- {"type", "text-multi"},
- {"label", translate:translate(Lang, "Message body")}],
- []}]
- end}.
+ [],
+ [{xmlcdata, "true"}]}]}];
+ true ->
+ [{xmlelement, "field",
+ [{"var", "subject"},
+ {"type", "text-single"},
+ {"label", translate:translate(Lang, "Subject")}],
+ []},
+ {xmlelement, "field",
+ [{"var", "body"},
+ {"type", "text-multi"},
+ {"label", translate:translate(Lang, "Message body")}],
+ []}]
+ end}.
join_lines([]) ->
[];
Proc = gen_mod:get_module_proc(LServer, ?PROCNAME),
case {Node, Body} of
- {"announce/motd/delete", _} ->
+ {?NS_ADMIN ++ "#delete-motd", _} ->
if Confirm ->
Proc ! {announce_motd_delete, From, To, Packet},
adhoc:produce_response(Response);
- true ->
+ true ->
adhoc:produce_response(Response)
end;
- {"announce/all-hosts/motd/delete", _} ->
+ {?NS_ADMIN ++ "#delete-motd-allhosts", _} ->
if Confirm ->
Proc ! {announce_all_hosts_motd_delete, From, To, Packet},
adhoc:produce_response(Response);
- true ->
+ true ->
adhoc:produce_response(Response)
end;
{_, []} ->
%% An announce message with no body is definitely an operator error.
%% Throw an error and give him/her a chance to send message again.
{error, ?ERRT_NOT_ACCEPTABLE(
- Lang,
- "No body provided for announce message")};
+ Lang,
+ "No body provided for announce message")};
%% Now send the packet to ?PROCNAME.
%% We don't use direct announce_* functions because it
%% leads to large delay in response and <iq/> queries processing
- {"announce/all", _} ->
+ {?NS_ADMIN ++ "#announce-all", _} ->
Proc ! {announce_all, From, To, Packet},
adhoc:produce_response(Response);
- {"announce/all-hosts/all", _} ->
+ {?NS_ADMIN ++ "#announce-all-allhosts", _} ->
Proc ! {announce_all_hosts_all, From, To, Packet},
adhoc:produce_response(Response);
- {"announce/online", _} ->
+ {?NS_ADMIN ++ "#announce", _} ->
Proc ! {announce_online, From, To, Packet},
adhoc:produce_response(Response);
- {"announce/all-hosts/online", _} ->
+ {?NS_ADMIN ++ "#announce-online-allhosts", _} ->
Proc ! {announce_all_hosts_online, From, To, Packet},
adhoc:produce_response(Response);
- {"announce/motd", _} ->
+ {?NS_ADMIN ++ "#set-motd", _} ->
Proc ! {announce_motd, From, To, Packet},
adhoc:produce_response(Response);
- {"announce/all-hosts/motd", _} ->
+ {?NS_ADMIN ++ "#motd-allhosts", _} ->
Proc ! {announce_all_hosts_motd, From, To, Packet},
adhoc:produce_response(Response);
- {"announce/motd/update", _} ->
+ {?NS_ADMIN ++ "#edit-motd", _} ->
Proc ! {announce_motd_update, From, To, Packet},
adhoc:produce_response(Response);
- {"announce/all-hosts/motd/update", _} ->
+ {?NS_ADMIN ++ "#edit-motd-allhosts", _} ->
Proc ! {announce_all_hosts_motd_update, From, To, Packet},
adhoc:produce_response(Response);
_ ->
get_title(Lang, "announce") ->
translate:translate(Lang, "Announcements");
-get_title(Lang, "announce/all") ->
+get_title(Lang, ?NS_ADMIN ++ "#announce-all") ->
translate:translate(Lang, "Send announcement to all users");
-get_title(Lang, "announce/all-hosts/all") ->
+get_title(Lang, ?NS_ADMIN ++ "#announce-all-allhosts") ->
translate:translate(Lang, "Send announcement to all users on all hosts");
-get_title(Lang, "announce/online") ->
+get_title(Lang, ?NS_ADMIN ++ "#announce") ->
translate:translate(Lang, "Send announcement to all online users");
-get_title(Lang, "announce/all-hosts/online") ->
+get_title(Lang, ?NS_ADMIN ++ "#announce-online-allhosts") ->
translate:translate(Lang, "Send announcement to all online users on all hosts");
-get_title(Lang, "announce/motd") ->
+get_title(Lang, ?NS_ADMIN ++ "#set-motd") ->
translate:translate(Lang, "Set message of the day and send to online users");
-get_title(Lang, "announce/all-hosts/motd") ->
+get_title(Lang, ?NS_ADMIN ++ "#motd-allhosts") ->
translate:translate(Lang, "Set message of the day on all hosts and send to online users");
-get_title(Lang, "announce/motd/update") ->
+get_title(Lang, ?NS_ADMIN ++ "#edit-motd") ->
translate:translate(Lang, "Update message of the day (don't send)");
-get_title(Lang, "announce/all-hosts/motd/update") ->
+get_title(Lang, ?NS_ADMIN ++ "#edit-motd-allhosts") ->
translate:translate(Lang, "Update message of the day on all hosts (don't send)");
-get_title(Lang, "announce/motd/delete") ->
+get_title(Lang, ?NS_ADMIN ++ "#delete-motd") ->
translate:translate(Lang, "Delete message of the day");
-get_title(Lang, "announce/all-hosts/motd/delete") ->
+get_title(Lang, ?NS_ADMIN ++ "#delete-motd-allhosts") ->
translate:translate(Lang, "Delete message of the day on all hosts").
-%-------------------------------------------------------------------------
+%%-------------------------------------------------------------------------
announce_all(From, To, Packet) ->
Host = To#jid.lserver,
allow ->
Local = jlib:make_jid("", To#jid.server, ""),
lists:foreach(
- fun({User, Server}) ->
- Dest = jlib:make_jid(User, Server, ""),
- ejabberd_router:route(Local, Dest, Packet)
- end, ejabberd_auth:get_vh_registered_users(Host))
+ fun({User, Server}) ->
+ Dest = jlib:make_jid(User, Server, ""),
+ ejabberd_router:route(Local, Dest, Packet)
+ end, ejabberd_auth:get_vh_registered_users(Host))
end.
announce_all_hosts_all(From, To, Packet) ->
allow ->
Local = jlib:make_jid("", To#jid.server, ""),
lists:foreach(
- fun({User, Server}) ->
- Dest = jlib:make_jid(User, Server, ""),
- ejabberd_router:route(Local, Dest, Packet)
- end, ejabberd_auth:dirty_get_registered_users())
+ fun({User, Server}) ->
+ Dest = jlib:make_jid(User, Server, ""),
+ ejabberd_router:route(Local, Dest, Packet)
+ end, ejabberd_auth:dirty_get_registered_users())
end.
announce_online(From, To, Packet) ->
Err = jlib:make_error_reply(Packet, ?ERR_FORBIDDEN),
ejabberd_router:route(To, From, Err);
allow ->
- announce_motd(Host, Packet)
+ announce_motd(Host, Packet)
end.
announce_all_hosts_motd(From, To, Packet) ->
ok
end.
-%-------------------------------------------------------------------------
+%%-------------------------------------------------------------------------
update_tables() ->
update_motd_table(),
%%% Id : $Id$
%%%----------------------------------------------------------------------
+%%% Implements most of XEP-0133: Service Administration Version 1.1 (2005-08-19)
+
-module(mod_configure).
-author('alexey@sevcom.net').
-vsn('$Revision$ ').
-include("jlib.hrl").
-include("adhoc.hrl").
+-define(T(Lang, Text), translate:translate(Lang, Text)).
+
+%% Copied from ejabberd_sm.erl
+-record(session, {sid, usr, us, priority, info}).
start(Host, _Opts) ->
ejabberd_hooks:add(disco_local_items, Host, ?MODULE, get_local_items, 50),
[{xmlelement, "identity",
[{"category", Category},
{"type", Type},
- {"name", translate:translate(Lang, Name)}], []}]).
+ {"name", ?T(Lang, Name)}], []}]).
-define(INFO_COMMAND(Name, Lang),
?INFO_IDENTITY("automation", "command-node", Name, Lang)).
+-define(NODEJID(To, Name, Node),
+ {xmlelement, "item",
+ [{"jid", jlib:jid_to_string(To)},
+ {"name", ?T(Lang, Name)},
+ {"node", Node}], []}).
+
+-define(NODE(Name, Node),
+ {xmlelement, "item",
+ [{"jid", Server},
+ {"name", ?T(Lang, Name)},
+ {"node", Node}], []}).
+
+-define(NS_ADMINX(Sub), ?NS_ADMIN++"#"++Sub).
+-define(NS_ADMINL(Sub), ["http:","jabber.org","protocol","admin", Sub]).
+tokenize(Node) -> string:tokens(Node, "/#").
+
get_sm_identity(Acc, _From, _To, Node, Lang) ->
case Node of
"config" ->
end.
get_local_identity(Acc, _From, _To, Node, Lang) ->
- LNode = string:tokens(Node, "/"),
+ LNode = tokenize(Node),
case LNode of
["running nodes", ENode] ->
?INFO_IDENTITY("ejabberd", "node", ENode, Lang);
?INFO_COMMAND("Import File", Lang);
["running nodes", _ENode, "import", "dir"] ->
?INFO_COMMAND("Import Directory", Lang);
+ ["running nodes", _ENode, "restart"] ->
+ ?INFO_COMMAND("Restart Service", Lang);
+ ["running nodes", _ENode, "shutdown"] ->
+ ?INFO_COMMAND("Shut Down Service", Lang);
+ ?NS_ADMINL("add-user") ->
+ ?INFO_COMMAND("Add User", Lang);
+ ?NS_ADMINL("delete-user") ->
+ ?INFO_COMMAND("Delete User", Lang);
+ ?NS_ADMINL("end-user-session") ->
+ ?INFO_COMMAND("End User Session", Lang);
+ ?NS_ADMINL("get-user-password") ->
+ ?INFO_COMMAND("Get User Password", Lang);
+ ?NS_ADMINL("change-user-password") ->
+ ?INFO_COMMAND("Change User Password", Lang);
+ ?NS_ADMINL("get-user-lastlogin") ->
+ ?INFO_COMMAND("Get User Last Login Time", Lang);
+ ?NS_ADMINL("user-stats") ->
+ ?INFO_COMMAND("Get User Statistics", Lang);
+ ?NS_ADMINL("get-registered-users-num") ->
+ ?INFO_COMMAND("Get Number of Registered Users", Lang);
+ ?NS_ADMINL("get-online-users-num") ->
+ ?INFO_COMMAND("Get Number of Online Users", Lang);
["config", "hostname"] ->
?INFO_COMMAND("Host Name", Lang);
["config", "acls"] ->
%%%-----------------------------------------------------------------------
-define(INFO_RESULT(Allow, Feats),
- case Allow of
- deny ->
- {error, ?ERR_FORBIDDEN};
- allow ->
- {result, Feats}
- end).
+ case Allow of
+ deny ->
+ {error, ?ERR_FORBIDDEN};
+ allow ->
+ {result, Feats}
+ end).
get_sm_features(Acc, From, #jid{lserver = LServer} = _To, Node, _Lang) ->
case gen_mod:is_loaded(LServer, mod_adhoc) of
false ->
Acc;
_ ->
- LNode = string:tokens(Node, "/"),
+ LNode = tokenize(Node),
Allow = acl:match_rule(LServer, configure, From),
case LNode of
["config"] ->
?INFO_RESULT(Allow, []);
+ ["user"] ->
+ ?INFO_RESULT(Allow, []);
["online users"] ->
?INFO_RESULT(Allow, []);
["all users"] ->
?INFO_RESULT(Allow, []);
["running nodes", _ENode, "import", _] ->
?INFO_RESULT(Allow, [?NS_COMMANDS]);
+ ["running nodes", _ENode, "restart"] ->
+ ?INFO_RESULT(Allow, [?NS_COMMANDS]);
+ ["running nodes", _ENode, "shutdown"] ->
+ ?INFO_RESULT(Allow, [?NS_COMMANDS]);
["config", _] ->
?INFO_RESULT(Allow, [?NS_COMMANDS]);
+ ["http:" | _] ->
+ ?INFO_RESULT(Allow, [?NS_COMMANDS]);
_ ->
Acc
end
end,
Nodes = [{xmlelement, "item",
[{"jid", jlib:jid_to_string(To)},
- {"name", translate:translate(Lang, "Configuration")},
+ {"name", ?T(Lang, "Configuration")},
{"node", "config"}], []}],
{result, Items ++ Nodes};
_ ->
end,
case {acl:match_rule(LServer, configure, From), Node} of
{allow, ""} ->
- Nodes = [{xmlelement, "item",
- [{"jid", jlib:jid_to_string(To)},
- {"name", translate:translate(Lang, "Configuration")},
- {"node", "config"}], []}],
+ Nodes = [?NODEJID(To, "Configuration", "config"),
+ ?NODEJID(To, "User Management", "user")],
{result, Items ++ Nodes ++ get_user_resources(User, Server)};
{allow, "config"} ->
{result, []};
Nodes = recursively_get_local_items(LServer, "", Server, Lang),
Nodes1 = lists:filter(
fun(N) ->
- Nd = xml:get_tag_attr_s("node", N),
- F = get_local_features([], From, To, Nd, Lang),
- case F of
- {result, [?NS_COMMANDS]} ->
- true;
- _ ->
- false
- end
+ Nd = xml:get_tag_attr_s("node", N),
+ F = get_local_features([], From, To, Nd, Lang),
+ case F of
+ {result, [?NS_COMMANDS]} ->
+ true;
+ _ ->
+ false
+ end
end, Nodes),
{result, Items ++ Nodes1};
_ ->
[];
recursively_get_local_items(LServer, Node, Server, Lang) ->
- LNode = string:tokens(Node, "/"),
+ LNode = tokenize(Node),
Items = case get_local_items(LServer, LNode, Server, Lang) of
{result, Res} ->
Res;
[]
end,
Nodes = lists:flatten(
- lists:map(
- fun(N) ->
- S = xml:get_tag_attr_s("jid", N),
- Nd = xml:get_tag_attr_s("node", N),
- if (S /= Server) or (Nd == "") ->
- [];
- true ->
- [N, recursively_get_local_items(
- LServer, Nd, Server, Lang)]
- end
- end, Items)),
+ lists:map(
+ fun(N) ->
+ S = xml:get_tag_attr_s("jid", N),
+ Nd = xml:get_tag_attr_s("node", N),
+ if (S /= Server) or (Nd == "") ->
+ [];
+ true ->
+ [N, recursively_get_local_items(
+ LServer, Nd, Server, Lang)]
+ end
+ end, Items)),
Nodes.
%%%-----------------------------------------------------------------------
-define(ITEMS_RESULT(Allow, LNode, Fallback),
- case Allow of
- deny ->
- Fallback;
- allow ->
- case get_local_items(LServer, LNode,
- jlib:jid_to_string(To), Lang) of
- {result, Res} ->
- {result, Res};
- {error, Error} ->
- {error, Error}
- end
- end).
+ case Allow of
+ deny ->
+ Fallback;
+ allow ->
+ case get_local_items(LServer, LNode,
+ jlib:jid_to_string(To), Lang) of
+ {result, Res} ->
+ {result, Res};
+ {error, Error} ->
+ {error, Error}
+ end
+ end).
get_local_items(Acc, From, #jid{lserver = LServer} = To, "", Lang) ->
case gen_mod:is_loaded(LServer, mod_adhoc) of
false ->
Acc;
_ ->
- LNode = string:tokens(Node, "/"),
+ LNode = tokenize(Node),
Allow = acl:match_rule(LServer, configure, From),
case LNode of
["config"] ->
?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
+ ["user"] ->
+ ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
["online users"] ->
?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
["all users"] ->
?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
["running nodes", _ENode, "import", _] ->
?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
+ ["running nodes", _ENode, "restart"] ->
+ ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
+ ["running nodes", _ENode, "shutdown"] ->
+ ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
["config", _] ->
?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
+ ?NS_ADMINL(_) ->
+ ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
_ ->
Acc
end
%%%-----------------------------------------------------------------------
--define(NODE(Name, Node),
- {xmlelement, "item",
- [{"jid", Server},
- {"name", translate:translate(Lang, Name)},
- {"node", Node}], []}).
-
get_local_items(_Host, [], Server, Lang) ->
{result,
[?NODE("Configuration", "config"),
+ ?NODE("User Management", "user"),
?NODE("Online Users", "online users"),
?NODE("All Users", "all users"),
?NODE("Outgoing s2s Connections", "outgoing s2s"),
[?NODE("Host Name", "config/hostname"),
?NODE("Access Control Lists", "config/acls"),
?NODE("Access Rules", "config/access")
- % Too expensive on big hosts
- %?NODE("Remove Users", "config/remusers")
]};
get_local_items(_Host, ["config", _], _Server, _Lang) ->
{result, []};
+get_local_items(_Host, ["user"], Server, Lang) ->
+ {result,
+ [?NODE("Add User", ?NS_ADMINX("add-user")),
+ ?NODE("Delete User", ?NS_ADMINX("delete-user")),
+ ?NODE("End User Session", ?NS_ADMINX("end-user-session")),
+ ?NODE("Get User Password", ?NS_ADMINX("get-user-password")),
+ ?NODE("Change User Password",?NS_ADMINX("change-user-password")),
+ ?NODE("Get User Last Login Time", ?NS_ADMINX("get-user-lastlogin")),
+ ?NODE("Get User Statistics", ?NS_ADMINX("user-stats")),
+ ?NODE("Get Number of Registered Users",?NS_ADMINX("get-registered-users-num")),
+ ?NODE("Get Number of Online Users",?NS_ADMINX("get-online-users-num"))
+ ]};
+
+get_local_items(_Host, ["http:" | _], _Server, _Lang) ->
+ {result, []};
+
get_local_items(Host, ["online users"], _Server, _Lang) ->
{result, get_online_vh_users(Host)};
{"name", U ++ "@" ++ S}], []}
end, Sub)
end of
- {'EXIT', _Reason} ->
- ?ERR_NOT_ACCEPTABLE;
- Res ->
- {result, Res}
- end
+ {'EXIT', _Reason} ->
+ ?ERR_NOT_ACCEPTABLE;
+ Res ->
+ {result, Res}
+ end
end;
get_local_items(Host, ["outgoing s2s"], _Server, Lang) ->
?NODE("Modules", "running nodes/" ++ ENode ++ "/modules"),
?NODE("Backup Management", "running nodes/" ++ ENode ++ "/backup"),
?NODE("Import Users From jabberd 1.4 Spool Files",
- "running nodes/" ++ ENode ++ "/import")
+ "running nodes/" ++ ENode ++ "/import"),
+ ?NODE("Restart Service", "running nodes/" ++ ENode ++ "/restart"),
+ ?NODE("Shut Down Service", "running nodes/" ++ ENode ++ "/shutdown")
]};
get_local_items(_Host, ["running nodes", _ENode, "DB"], _Server, _Lang) ->
get_local_items(_Host, ["running nodes", _ENode, "import", _], _Server, _Lang) ->
{result, []};
+get_local_items(_Host, ["running nodes", _ENode, "restart"], _Server, _Lang) ->
+ {result, []};
+
+get_local_items(_Host, ["running nodes", _ENode, "shutdown"], _Server, _Lang) ->
+ {result, []};
+
get_local_items(_Host, _, _Server, _Lang) ->
{error, ?ERR_ITEM_NOT_FOUND}.
{"name",
lists:flatten(
io_lib:format(
- translate:translate(Lang, "To ~s"), [T]))}],
+ ?T(Lang, "To ~s"), [T]))}],
[]}
end, lists:usort(TConns))
end.
{"name",
lists:flatten(
io_lib:format(
- translate:translate(Lang, "From ~s"), [F]))}],
+ ?T(Lang, "From ~s"), [F]))}],
[]}
end, lists:keysort(1, lists:filter(fun(E) ->
element(2, E) == To
end, lists:sort(DBNodes))
end.
-%-------------------------------------------------------------------------
+%%-------------------------------------------------------------------------
-define(COMMANDS_RESULT(Allow, From, To, Request),
- case Allow of
- deny ->
- {error, ?ERR_FORBIDDEN};
- allow ->
- adhoc_local_commands(From, To, Request)
- end).
+ case Allow of
+ deny ->
+ {error, ?ERR_FORBIDDEN};
+ allow ->
+ adhoc_local_commands(From, To, Request)
+ end).
adhoc_local_commands(Acc, From, #jid{lserver = LServer} = To,
#adhoc_request{node = Node} = Request) ->
- LNode = string:tokens(Node, "/"),
+ LNode = tokenize(Node),
Allow = acl:match_rule(LServer, configure, From),
case LNode of
["running nodes", _ENode, "DB"] ->
?COMMANDS_RESULT(Allow, From, To, Request);
["running nodes", _ENode, "import", _] ->
?COMMANDS_RESULT(Allow, From, To, Request);
+ ["running nodes", _ENode, "restart"] ->
+ ?COMMANDS_RESULT(Allow, From, To, Request);
+ ["running nodes", _ENode, "shutdown"] ->
+ ?COMMANDS_RESULT(Allow, From, To, Request);
["config", _] ->
?COMMANDS_RESULT(Allow, From, To, Request);
+ ?NS_ADMINL(_) ->
+ ?COMMANDS_RESULT(Allow, From, To, Request);
_ ->
Acc
end.
-adhoc_local_commands(_From, #jid{lserver = LServer} = _To,
+adhoc_local_commands(From, #jid{lserver = LServer} = _To,
#adhoc_request{lang = Lang,
node = Node,
sessionid = SessionID,
action = Action,
xdata = XData} = Request) ->
- LNode = string:tokens(Node, "/"),
+ LNode = tokenize(Node),
%% If the "action" attribute is not present, it is
%% understood as "execute". If there was no <actions/>
%% element in the first response (which there isn't in our
Request,
#adhoc_response{status = executing,
elements = Form});
+ {result, Status, Form} ->
+ adhoc:produce_response(
+ Request,
+ #adhoc_response{status = Status,
+ elements = Form});
{error, Error} ->
{error, Error}
end;
invalid ->
{error, ?ERR_BAD_REQUEST};
Fields ->
- case set_form(LServer, LNode, Lang, Fields) of
- {result, _Res} ->
+ 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.
+-define(TVFIELD(Type, Var, Val),
+ {xmlelement, "field", [{"type", Type},
+ {"var", Var}],
+ [{xmlelement, "value", [], [{xmlcdata, Val}]}]}).
+-define(HFIELD(), ?TVFIELD("hidden", "FORM_TYPE", ?NS_ADMIN)).
+
-define(TLFIELD(Type, Label, Var),
{xmlelement, "field", [{"type", Type},
- {"label", translate:translate(Lang, Label)},
+ {"label", ?T(Lang, Label)},
{"var", Var}], []}).
-define(XFIELD(Type, Label, Var, Val),
{xmlelement, "field", [{"type", Type},
- {"label", translate:translate(Lang, Label)},
+ {"label", ?T(Lang, Label)},
{"var", Var}],
[{xmlelement, "value", [], [{xmlcdata, Val}]}]}).
+-define(XMFIELD(Type, Label, Var, Vals),
+ {xmlelement, "field", [{"type", Type},
+ {"label", ?T(Lang, Label)},
+ {"var", Var}],
+ [{xmlelement, "value", [], [{xmlcdata,Val}]} || Val <- Vals]}).
+
-define(TABLEFIELD(Table, Val),
{xmlelement, "field", [{"type", "list-single"},
{"label", atom_to_list(Table)},
{"var", atom_to_list(Table)}],
[{xmlelement, "value", [], [{xmlcdata, atom_to_list(Val)}]},
{xmlelement, "option", [{"label",
- translate:translate(Lang, "RAM copy")}],
+ ?T(Lang, "RAM copy")}],
[{xmlelement, "value", [], [{xmlcdata, "ram_copies"}]}]},
{xmlelement, "option", [{"label",
- translate:translate(Lang,
- "RAM and disc copy")}],
+ ?T(Lang,
+ "RAM and disc copy")}],
[{xmlelement, "value", [], [{xmlcdata, "disc_copies"}]}]},
{xmlelement, "option", [{"label",
- translate:translate(Lang,
- "Disc only copy")}],
+ ?T(Lang,
+ "Disc only copy")}],
[{xmlelement, "value", [], [{xmlcdata, "disc_only_copies"}]}]},
{xmlelement, "option", [{"label",
- translate:translate(Lang, "Remote copy")}],
+ ?T(Lang, "Remote copy")}],
[{xmlelement, "value", [], [{xmlcdata, "unknown"}]}]}
]}).
Tables ->
STables = lists:sort(Tables),
{result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}],
- [{xmlelement, "title", [],
+ [?HFIELD(),
+ {xmlelement, "title", [],
[{xmlcdata,
- translate:translate(
- Lang, "Database Tables Configuration at ") ++
- ENode}]},
+ ?T(
+ Lang, "Database Tables Configuration at ") ++
+ ENode}]},
{xmlelement, "instructions", [],
[{xmlcdata,
- translate:translate(
- Lang, "Choose storage type of tables")}]} |
+ ?T(
+ Lang, "Choose storage type of tables")}]} |
lists:map(
fun(Table) ->
case rpc:call(Node,
?TABLEFIELD(Table, Type)
end
end, STables)
- ]}]}
+ ]}]}
end
end;
Modules ->
SModules = lists:sort(Modules),
{result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}],
- [{xmlelement, "title", [],
+ [?HFIELD(),
+ {xmlelement, "title", [],
[{xmlcdata,
- translate:translate(
- Lang, "Stop Modules at ") ++ ENode}]},
+ ?T(
+ Lang, "Stop Modules at ") ++ ENode}]},
{xmlelement, "instructions", [],
[{xmlcdata,
- translate:translate(
- Lang, "Choose modules to stop")}]} |
+ ?T(
+ Lang, "Choose modules to stop")}]} |
lists:map(fun(M) ->
S = atom_to_list(M),
?XFIELD("boolean", S, S, "0")
end, SModules)
- ]}]}
+ ]}]}
end
end;
get_form(_Host, ["running nodes", ENode, "modules", "start"], Lang) ->
{result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}],
- [{xmlelement, "title", [],
+ [?HFIELD(),
+ {xmlelement, "title", [],
[{xmlcdata,
- translate:translate(
- Lang, "Start Modules at ") ++ ENode}]},
+ ?T(
+ Lang, "Start Modules at ") ++ ENode}]},
{xmlelement, "instructions", [],
[{xmlcdata,
- translate:translate(
- Lang, "Enter list of {Module, [Options]}")}]},
- {xmlelement, "field", [{"type", "text-multi"},
- {"label",
- translate:translate(
- Lang, "List of modules to start")},
- {"var", "modules"}],
- [{xmlelement, "value", [], [{xmlcdata, "[]."}]}]
- }
- ]}]};
+ ?T(
+ Lang, "Enter list of {Module, [Options]}")}]},
+ ?XFIELD("text-multi", "List of modules to start", "modules", "[].")
+ ]}]};
get_form(_Host, ["running nodes", ENode, "backup", "backup"], Lang) ->
{result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}],
- [{xmlelement, "title", [],
+ [?HFIELD(),
+ {xmlelement, "title", [],
[{xmlcdata,
- translate:translate(
- Lang, "Backup to File at ") ++ ENode}]},
+ ?T(
+ Lang, "Backup to File at ") ++ ENode}]},
{xmlelement, "instructions", [],
[{xmlcdata,
- translate:translate(
- Lang, "Enter path to backup file")}]},
- {xmlelement, "field", [{"type", "text-single"},
- {"label",
- translate:translate(
- Lang, "Path to File")},
- {"var", "path"}],
- [{xmlelement, "value", [], [{xmlcdata, ""}]}]
- }
- ]}]};
+ ?T(
+ Lang, "Enter path to backup file")}]},
+ ?XFIELD("text-single", "Path to File", "path", "")
+ ]}]};
get_form(_Host, ["running nodes", ENode, "backup", "restore"], Lang) ->
{result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}],
- [{xmlelement, "title", [],
+ [?HFIELD(),
+ {xmlelement, "title", [],
[{xmlcdata,
- translate:translate(
- Lang, "Restore Backup from File at ") ++ ENode}]},
+ ?T(
+ Lang, "Restore Backup from File at ") ++ ENode}]},
{xmlelement, "instructions", [],
[{xmlcdata,
- translate:translate(
- Lang, "Enter path to backup file")}]},
- {xmlelement, "field", [{"type", "text-single"},
- {"label",
- translate:translate(
- Lang, "Path to File")},
- {"var", "path"}],
- [{xmlelement, "value", [], [{xmlcdata, ""}]}]
- }
- ]}]};
+ ?T(
+ Lang, "Enter path to backup file")}]},
+ ?XFIELD("text-single", "Path to File", "path", "")
+ ]}]};
get_form(_Host, ["running nodes", ENode, "backup", "textfile"], Lang) ->
{result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}],
- [{xmlelement, "title", [],
+ [?HFIELD(),
+ {xmlelement, "title", [],
[{xmlcdata,
- translate:translate(
- Lang, "Dump Backup to Text File at ") ++ ENode}]},
+ ?T(
+ Lang, "Dump Backup to Text File at ") ++ ENode}]},
{xmlelement, "instructions", [],
[{xmlcdata,
- translate:translate(
- Lang, "Enter path to text file")}]},
- {xmlelement, "field", [{"type", "text-single"},
- {"label",
- translate:translate(
- Lang, "Path to File")},
- {"var", "path"}],
- [{xmlelement, "value", [], [{xmlcdata, ""}]}]
- }
- ]}]};
+ ?T(
+ Lang, "Enter path to text file")}]},
+ ?XFIELD("text-single", "Path to File", "path", "")
+ ]}]};
get_form(_Host, ["running nodes", ENode, "import", "file"], Lang) ->
{result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}],
- [{xmlelement, "title", [],
+ [?HFIELD(),
+ {xmlelement, "title", [],
[{xmlcdata,
- translate:translate(
- Lang, "Import User from File at ") ++ ENode}]},
+ ?T(
+ Lang, "Import User from File at ") ++ ENode}]},
{xmlelement, "instructions", [],
[{xmlcdata,
- translate:translate(
- Lang, "Enter path to jabberd1.4 spool file")}]},
- {xmlelement, "field", [{"type", "text-single"},
- {"label",
- translate:translate(
- Lang, "Path to File")},
- {"var", "path"}],
- [{xmlelement, "value", [], [{xmlcdata, ""}]}]
- }
- ]}]};
+ ?T(
+ Lang, "Enter path to jabberd1.4 spool file")}]},
+ ?XFIELD("text-single", "Path to File", "path", "")
+ ]}]};
get_form(_Host, ["running nodes", ENode, "import", "dir"], Lang) ->
{result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}],
- [{xmlelement, "title", [],
+ [?HFIELD(),
+ {xmlelement, "title", [],
[{xmlcdata,
- translate:translate(
- Lang, "Import Users from Dir at ") ++ ENode}]},
+ ?T(
+ Lang, "Import Users from Dir at ") ++ ENode}]},
{xmlelement, "instructions", [],
[{xmlcdata,
- translate:translate(
- Lang, "Enter path to jabberd1.4 spool dir")}]},
- {xmlelement, "field", [{"type", "text-single"},
- {"label",
- translate:translate(
- Lang, "Path to Dir")},
- {"var", "path"}],
- [{xmlelement, "value", [], [{xmlcdata, ""}]}]
- }
- ]}]};
+ ?T(
+ Lang, "Enter path to jabberd1.4 spool dir")}]},
+ ?XFIELD("text-single", "Path to Dir", "path", "")
+ ]}]};
+
+get_form(_Host, ["running nodes", _ENode, "restart"], Lang) ->
+ Make_option =
+ fun(LabelNum, LabelUnit, Value)->
+ {xmlelement, "option",
+ [{"label", LabelNum ++ ?T(Lang, LabelUnit)}],
+ [{xmlelement, "value", [], [{xmlcdata, Value}]}]}
+ end,
+ {result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}],
+ [?HFIELD(),
+ {xmlelement, "title", [],
+ [{xmlcdata, ?T(Lang, "Restart Service")}]},
+ {xmlelement, "field",
+ [{"type", "list-single"},
+ {"label", ?T(Lang, "Time delay")},
+ {"var", "delay"}],
+ [Make_option("", "immediately", "1"),
+ Make_option("15 ", "seconds", "15"),
+ Make_option("30 ", "seconds", "30"),
+ Make_option("60 ", "seconds", "60"),
+ Make_option("90 ", "seconds", "90"),
+ Make_option("2 ", "minutes", "120"),
+ Make_option("3 ", "minutes", "180"),
+ Make_option("4 ", "minutes", "240"),
+ Make_option("5 ", "minutes", "300"),
+ Make_option("10 ", "minutes", "600"),
+ Make_option("15 ", "minutes", "900"),
+ Make_option("30 ", "minutes", "1800"),
+ {xmlelement, "required", [], []}
+ ]},
+ {xmlelement, "field",
+ [{"type", "fixed"},
+ {"label", ?T(Lang, "Send announcement to all online users on all hosts")}],
+ []},
+ {xmlelement, "field",
+ [{"var", "subject"},
+ {"type", "text-single"},
+ {"label", ?T(Lang, "Subject")}],
+ []},
+ {xmlelement, "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)->
+ {xmlelement, "option",
+ [{"label", LabelNum ++ ?T(Lang, LabelUnit)}],
+ [{xmlelement, "value", [], [{xmlcdata, Value}]}]}
+ end,
+ {result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}],
+ [?HFIELD(),
+ {xmlelement, "title", [],
+ [{xmlcdata, ?T(Lang, "Shut Down Service")}]},
+ {xmlelement, "field",
+ [{"type", "list-single"},
+ {"label", ?T(Lang, "Time delay")},
+ {"var", "delay"}],
+ [Make_option("", "immediately", "1"),
+ Make_option("15 ", "seconds", "15"),
+ Make_option("30 ", "seconds", "30"),
+ Make_option("60 ", "seconds", "60"),
+ Make_option("90 ", "seconds", "90"),
+ Make_option("2 ", "minutes", "120"),
+ Make_option("3 ", "minutes", "180"),
+ Make_option("4 ", "minutes", "240"),
+ Make_option("5 ", "minutes", "300"),
+ Make_option("10 ", "minutes", "600"),
+ Make_option("15 ", "minutes", "900"),
+ Make_option("30 ", "minutes", "1800"),
+ {xmlelement, "required", [], []}
+ ]},
+ {xmlelement, "field",
+ [{"type", "fixed"},
+ {"label", ?T(Lang, "Send announcement to all online users on all hosts")}],
+ []},
+ {xmlelement, "field",
+ [{"var", "subject"},
+ {"type", "text-single"},
+ {"label", ?T(Lang, "Subject")}],
+ []},
+ {xmlelement, "field",
+ [{"var", "announcement"},
+ {"type", "text-multi"},
+ {"label", ?T(Lang, "Message body")}],
+ []}
+ ]}]};
get_form(_Host, ["config", "hostname"], Lang) ->
{result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}],
- [{xmlelement, "title", [],
+ [?HFIELD(),
+ {xmlelement, "title", [],
[{xmlcdata,
- translate:translate(
- Lang, "Hostname Configuration")}]},
+ ?T(
+ Lang, "Hostname Configuration")}]},
{xmlelement, "instructions", [],
[{xmlcdata,
- translate:translate(
- Lang, "Choose host name")}]},
+ ?T(
+ Lang, "Choose host name")}]},
{xmlelement, "field", [{"type", "text-single"},
{"label",
- translate:translate(Lang,
- "Host name")},
+ ?T(Lang,
+ "Host name")},
{"var", "hostname"}],
[{xmlelement, "value", [], [{xmlcdata, ?MYNAME}]}]}
- ]}]};
+ ]}]};
get_form(_Host, ["config", "acls"], Lang) ->
{result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}],
- [{xmlelement, "title", [],
+ [?HFIELD(),
+ {xmlelement, "title", [],
[{xmlcdata,
- translate:translate(
- Lang, "Access Control List Configuration")}]},
- %{xmlelement, "instructions", [],
- % [{xmlcdata,
- % translate:translate(
- % Lang, "")}]},
+ ?T(
+ Lang, "Access Control List Configuration")}]},
{xmlelement, "field", [{"type", "text-multi"},
{"label",
- translate:translate(
- Lang, "Access control lists")},
+ ?T(
+ Lang, "Access control lists")},
{"var", "acls"}],
lists:map(fun(S) ->
- {xmlelement, "value", [], [{xmlcdata, S}]}
+ {xmlelement, "value", [], [{xmlcdata, S}]}
end,
string:tokens(
lists:flatten(io_lib:format("~p.",
[ets:tab2list(acl)])),
"\n"))
}
- ]}]};
+ ]}]};
get_form(_Host, ["config", "access"], Lang) ->
{result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}],
- [{xmlelement, "title", [],
+ [?HFIELD(),
+ {xmlelement, "title", [],
[{xmlcdata,
- translate:translate(
- Lang, "Access Configuration")}]},
- %{xmlelement, "instructions", [],
- % [{xmlcdata,
- % translate:translate(
- % Lang, "")}]},
+ ?T(
+ Lang, "Access Configuration")}]},
{xmlelement, "field", [{"type", "text-multi"},
{"label",
- translate:translate(
- Lang, "Access rules")},
+ ?T(
+ Lang, "Access rules")},
{"var", "access"}],
lists:map(fun(S) ->
- {xmlelement, "value", [], [{xmlcdata, S}]}
+ {xmlelement, "value", [], [{xmlcdata, S}]}
end,
string:tokens(
lists:flatten(
])),
"\n"))
}
- ]}]};
+ ]}]};
-get_form(Host, ["config", "remusers"], Lang) ->
+get_form(_Host, ?NS_ADMINL("add-user"), Lang) ->
{result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}],
- [{xmlelement, "title", [],
- [{xmlcdata,
- translate:translate(
- Lang, "Remove Users")}]},
- {xmlelement, "instructions", [],
- [{xmlcdata,
- translate:translate(
- Lang, "Choose users to remove")}]}] ++
- case catch ejabberd_auth:get_vh_registered_users(Host) of
- {'EXIT', _Reason} ->
- [];
- Users ->
- lists:map(fun(U) ->
- ?XFIELD("boolean", U, U, "0")
- end, lists:sort(Users))
- end
- }]};
+ [?HFIELD(),
+ {xmlelement, "title", [],
+ [{xmlcdata, ?T(Lang, "Add User")}]},
+ {xmlelement, "field",
+ [{"type", "jid-single"},
+ {"label", ?T(Lang, "Jabber ID")},
+ {"var", "accountjid"}],
+ [{xmlelement, "required", [], []}]},
+ {xmlelement, "field",
+ [{"type", "text-private"},
+ {"label", ?T(Lang, "Password")},
+ {"var", "password"}],
+ [{xmlelement, "required", [], []}]},
+ {xmlelement, "field",
+ [{"type", "text-private"},
+ {"label", ?T(Lang, "Password Verification")},
+ {"var", "password-verify"}],
+ [{xmlelement, "required", [], []}]}
+ ]}]};
+
+get_form(_Host, ?NS_ADMINL("delete-user"), Lang) ->
+ {result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}],
+ [?HFIELD(),
+ {xmlelement, "title", [],
+ [{xmlcdata, ?T(Lang, "Delete User")}]},
+ {xmlelement, "field",
+ [{"type", "jid-multi"},
+ {"label", ?T(Lang, "Jabber ID")},
+ {"var", "accountjids"}],
+ [{xmlelement, "required", [], []}]}
+ ]}]};
+
+get_form(_Host, ?NS_ADMINL("end-user-session"), Lang) ->
+ {result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}],
+ [?HFIELD(),
+ {xmlelement, "title", [],
+ [{xmlcdata, ?T(Lang, "End User Session")}]},
+ {xmlelement, "field",
+ [{"type", "jid-single"},
+ {"label", ?T(Lang, "Jabber ID")},
+ {"var", "accountjid"}],
+ [{xmlelement, "required", [], []}]}
+ ]}]};
+
+get_form(_Host, ?NS_ADMINL("get-user-password"), Lang) ->
+ {result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}],
+ [?HFIELD(),
+ {xmlelement, "title", [],
+ [{xmlcdata, ?T(Lang, "Get User Password")}]},
+ {xmlelement, "field",
+ [{"type", "jid-single"},
+ {"label", ?T(Lang, "Jabber ID")},
+ {"var", "accountjid"}],
+ [{xmlelement, "required", [], []}]}
+ ]}]};
+
+get_form(_Host, ?NS_ADMINL("change-user-password"), Lang) ->
+ {result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}],
+ [?HFIELD(),
+ {xmlelement, "title", [],
+ [{xmlcdata, ?T(Lang, "Get User Password")}]},
+ {xmlelement, "field",
+ [{"type", "jid-single"},
+ {"label", ?T(Lang, "Jabber ID")},
+ {"var", "accountjid"}],
+ [{xmlelement, "required", [], []}]},
+ {xmlelement, "field",
+ [{"type", "text-private"},
+ {"label", ?T(Lang, "Password")},
+ {"var", "password"}],
+ [{xmlelement, "required", [], []}]}
+ ]}]};
+
+get_form(_Host, ?NS_ADMINL("get-user-lastlogin"), Lang) ->
+ {result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}],
+ [?HFIELD(),
+ {xmlelement, "title", [],
+ [{xmlcdata, ?T(Lang, "Get User Last Login Time")}]},
+ {xmlelement, "field",
+ [{"type", "jid-single"},
+ {"label", ?T(Lang, "Jabber ID")},
+ {"var", "accountjid"}],
+ [{xmlelement, "required", [], []}]}
+ ]}]};
+
+get_form(_Host, ?NS_ADMINL("user-stats"), Lang) ->
+ {result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}],
+ [?HFIELD(),
+ {xmlelement, "title", [],
+ [{xmlcdata, ?T(Lang, "Get User Statistics")}]},
+ {xmlelement, "field",
+ [{"type", "jid-single"},
+ {"label", ?T(Lang, "Jabber ID")},
+ {"var", "accountjid"}],
+ [{xmlelement, "required", [], []}]}
+ ]}]};
+
+get_form(Host, ?NS_ADMINL("get-registered-users-num"), Lang) ->
+ [Num] = io_lib:format("~p", [ejabberd_auth:get_vh_registered_users_number(Host)]),
+ {result, completed,
+ [{xmlelement, "x",
+ [{"xmlns", ?NS_XDATA}],
+ [?HFIELD(),
+ {xmlelement,
+ "field",
+ [{"type", "jid-single"},
+ {"label", ?T(Lang, "Number of registered users")},
+ {"var", "registeredusersnum"}],
+ [{xmlelement, "value", [], [{xmlcdata, Num}]}]
+ }]}]};
+
+get_form(Host, ?NS_ADMINL("get-online-users-num"), Lang) ->
+ Num = io_lib:format("~p", [length(ejabberd_sm:get_vh_session_list(Host))]),
+ {result, completed,
+ [{xmlelement, "x",
+ [{"xmlns", ?NS_XDATA}],
+ [?HFIELD(),
+ {xmlelement,
+ "field",
+ [{"type", "jid-single"},
+ {"label", ?T(Lang, "Number of online users")},
+ {"var", "onlineusersnum"}],
+ [{xmlelement, "value", [], [{xmlcdata, Num}]}]
+ }]}]};
get_form(_Host, _, _Lang) ->
{error, ?ERR_SERVICE_UNAVAILABLE}.
-set_form(_Host, ["running nodes", ENode, "DB"], _Lang, XData) ->
+set_form(_From, _Host, ["running nodes", ENode, "DB"], _Lang, XData) ->
case search_running_node(ENode) of
false ->
{error, ?ERR_ITEM_NOT_FOUND};
Node ->
lists:foreach(
fun({SVar, SVals}) ->
- % We believe that this is allowed only for good people
+ %% We believe that this is allowed only for good people
Table = list_to_atom(SVar),
Type = case SVals of
["unknown"] -> unknown;
{result, []}
end;
-set_form(Host, ["running nodes", ENode, "modules", "stop"], _Lang, XData) ->
+set_form(_From, Host, ["running nodes", ENode, "modules", "stop"], _Lang, XData) ->
case search_running_node(ENode) of
false ->
{error, ?ERR_ITEM_NOT_FOUND};
{result, []}
end;
-set_form(Host, ["running nodes", ENode, "modules", "start"], _Lang, XData) ->
+set_form(_From, Host, ["running nodes", ENode, "modules", "start"], _Lang, XData) ->
case search_running_node(ENode) of
false ->
{error, ?ERR_ITEM_NOT_FOUND};
end;
-set_form(_Host, ["running nodes", ENode, "backup", "backup"], _Lang, XData) ->
+set_form(_From, _Host, ["running nodes", ENode, "backup", "backup"], _Lang, XData) ->
case search_running_node(ENode) of
false ->
{error, ?ERR_ITEM_NOT_FOUND};
{error, ?ERR_INTERNAL_SERVER_ERROR};
_ ->
{result, []}
- end;
+ end;
_ ->
{error, ?ERR_BAD_REQUEST}
end
end;
-set_form(_Host, ["running nodes", ENode, "backup", "restore"], _Lang, XData) ->
+set_form(_From, _Host, ["running nodes", ENode, "backup", "restore"], _Lang, XData) ->
case search_running_node(ENode) of
false ->
{error, ?ERR_ITEM_NOT_FOUND};
{error, ?ERR_INTERNAL_SERVER_ERROR};
_ ->
{result, []}
- end;
+ end;
_ ->
{error, ?ERR_BAD_REQUEST}
end
end;
-set_form(_Host, ["running nodes", ENode, "backup", "textfile"], _Lang, XData) ->
+set_form(_From, _Host, ["running nodes", ENode, "backup", "textfile"], _Lang, XData) ->
case search_running_node(ENode) of
false ->
{error, ?ERR_ITEM_NOT_FOUND};
{error, ?ERR_INTERNAL_SERVER_ERROR};
_ ->
{result, []}
- end;
+ end;
_ ->
{error, ?ERR_BAD_REQUEST}
end
end;
-set_form(_Host, ["running nodes", ENode, "import", "file"], _Lang, XData) ->
+set_form(_From, _Host, ["running nodes", ENode, "import", "file"], _Lang, XData) ->
case search_running_node(ENode) of
false ->
{error, ?ERR_ITEM_NOT_FOUND};
end;
-set_form(_Host, ["running nodes", ENode, "import", "dir"], _Lang, XData) ->
+set_form(_From, _Host, ["running nodes", ENode, "import", "dir"], _Lang, XData) ->
case search_running_node(ENode) of
false ->
{error, ?ERR_ITEM_NOT_FOUND};
end
end;
+set_form(From, Host, ["running nodes", ENode, "restart"], _Lang, XData) ->
+ stop_node(From, Host, ENode, restart, XData);
+
+set_form(From, Host, ["running nodes", ENode, "shutdown"], _Lang, XData) ->
+ stop_node(From, Host, ENode, stop, XData);
-set_form(_Host, ["config", "hostname"], _Lang, XData) ->
+set_form(_From, _Host, ["config", "hostname"], _Lang, XData) ->
case lists:keysearch("hostname", 1, XData) of
false ->
{error, ?ERR_BAD_REQUEST};
{error, ?ERR_BAD_REQUEST}
end;
-set_form(Host, ["config", "acls"], _Lang, XData) ->
+set_form(_From, Host, ["config", "acls"], _Lang, XData) ->
case lists:keysearch("acls", 1, XData) of
{value, {_, Strings}} ->
String = lists:foldl(fun(S, Res) ->
{error, ?ERR_BAD_REQUEST}
end;
-set_form(_Host, ["config", "access"], _Lang, XData) ->
+set_form(_From, _Host, ["config", "access"], _Lang, XData) ->
SetAccess =
fun(Rs) ->
mnesia:transaction(
case SetAccess(Rs) of
{atomic, _} ->
{result, []};
- E ->
- io:format("A: ~p~n", [E]),
+ _ ->
{error, ?ERR_BAD_REQUEST}
end;
_ ->
{error, ?ERR_BAD_REQUEST}
end;
-set_form(Host, ["config", "remusers"], _Lang, XData) ->
- lists:foreach(
- fun({Var, Vals}) ->
- case Vals of
- ["1"] ->
- catch ejabberd_auth:remove_user(Var, Host);
- _ ->
- ok
- end
- end, XData),
+set_form(_From, _Host, ?NS_ADMINL("add-user"), _Lang, XData) ->
+ AccountString = get_value("accountjid", XData),
+ Password = get_value("password", XData),
+ Password = get_value("password-verify", XData),
+ AccountJID = jlib:string_to_jid(AccountString),
+ User = AccountJID#jid.luser,
+ Server = AccountJID#jid.lserver,
+ true = lists:member(Server, ?MYHOSTS),
+ ejabberd_auth:try_register(User, Server, Password),
{result, []};
-set_form(_Host, _, _Lang, _XData) ->
+set_form(_From, _Host, ?NS_ADMINL("delete-user"), _Lang, XData) ->
+ AccountStringList = get_values("accountjids", XData),
+ [_|_] = AccountStringList,
+ ASL2 = lists:map(
+ fun(AccountString) ->
+ JID = jlib:string_to_jid(AccountString),
+ [_|_] = JID#jid.luser,
+ User = JID#jid.luser,
+ Server = JID#jid.lserver,
+ true = ejabberd_auth:is_user_exists(User, Server),
+ {User, Server}
+ end,
+ AccountStringList),
+ [ejabberd_auth:remove_user(User, Server) || {User, Server} <- ASL2],
+ {result, []};
+
+set_form(_From, _Host, ?NS_ADMINL("end-user-session"), _Lang, XData) ->
+ AccountString = get_value("accountjid", XData),
+ JID = jlib:string_to_jid(AccountString),
+ [_|_] = JID#jid.luser,
+ LUser = JID#jid.luser,
+ LServer = JID#jid.lserver,
+ %% Code copied from ejabberd_sm.erl
+ case JID#jid.lresource of
+ [] ->
+ SIDs = mnesia:dirty_select(session,
+ [{#session{sid = '$1', usr = {LUser, LServer, '_'}, _ = '_'}, [], ['$1']}]),
+ [Pid ! replaced || {_, Pid} <- SIDs];
+ R ->
+ [{_, Pid}] = mnesia:dirty_select(session,
+ [{#session{sid = '$1', usr = {LUser, LServer, R}, _ = '_'}, [], ['$1']}]),
+ Pid ! replaced
+ end,
+ {result, []};
+
+set_form(_From, _Host, ?NS_ADMINL("get-user-password"), Lang, XData) ->
+ AccountString = get_value("accountjid", XData),
+ JID = jlib:string_to_jid(AccountString),
+ [_|_] = JID#jid.luser,
+ User = JID#jid.luser,
+ Server = JID#jid.lserver,
+ Password = ejabberd_auth:get_password(User, Server),
+ true = is_list(Password),
+ {result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}],
+ [?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),
+ Password = get_value("password", XData),
+ JID = jlib:string_to_jid(AccountString),
+ [_|_] = JID#jid.luser,
+ User = JID#jid.luser,
+ Server = JID#jid.lserver,
+ true = ejabberd_auth:is_user_exists(User, Server),
+ ejabberd_auth:set_password(User, Server, Password),
+ {result, []};
+
+set_form(_From, _Host, ?NS_ADMINL("get-user-lastlogin"), Lang, XData) ->
+ AccountString = get_value("accountjid", XData),
+ JID = jlib:string_to_jid(AccountString),
+ [_|_] = JID#jid.luser,
+ User = JID#jid.luser,
+ Server = JID#jid.lserver,
+
+ %% Code copied from web/ejabberd_web_admin.erl
+ %% TODO: Update time format to XEP-0202: Entity Time
+ FLast =
+ case ejabberd_sm:get_user_resources(User, Server) of
+ [] ->
+ US = {User, Server},
+ case mnesia:dirty_read({last_activity, US}) of
+ [] ->
+ ?T(Lang, "Never");
+ [E] ->
+ Shift = element(3, E),
+ TimeStamp = {Shift div 1000000,
+ Shift rem 1000000,
+ 0},
+ {{Year, Month, Day}, {Hour, Minute, Second}} =
+ calendar:now_to_local_time(TimeStamp),
+ lists:flatten(
+ io_lib:format(
+ "~w-~.2.0w-~.2.0w ~.2.0w:~.2.0w:~.2.0w",
+ [Year, Month, Day, Hour, Minute, Second]))
+ end;
+ _ ->
+ ?T(Lang, "Online")
+ end,
+ {result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}, {"type", "result"}],
+ [?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),
+ JID = jlib:string_to_jid(AccountString),
+ [_|_] = JID#jid.luser,
+ User = JID#jid.luser,
+ Server = JID#jid.lserver,
+
+ Resources = ejabberd_sm:get_user_resources(User, Server),
+ IPs1 = [ejabberd_sm:get_user_ip(User, Server, Resource) || Resource <- Resources],
+ IPs = [inet_parse:ntoa(IP)++":"++integer_to_list(Port) || {IP, Port} <- IPs1],
+
+ Items = ejabberd_hooks:run_fold(roster_get, Server, [], [{User, Server}]),
+ Rostersize = integer_to_list(erlang:length(Items)),
+
+ {result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}],
+ [?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}.
+get_value(Field, XData) ->
+ hd(get_values(Field, XData)).
+get_values(Field, XData) ->
+ {value, {_, ValueList}} = lists:keysearch(Field, 1, XData),
+ ValueList.
search_running_node(SNode) ->
search_running_node(SNode, Nodes)
end.
+stop_node(From, Host, ENode, Action, XData) ->
+ Delay = list_to_integer(get_value("delay", XData)),
+ Subject = case get_value("subject", XData) of
+ [] -> [];
+ S -> [{xmlelement, "field", [{"var","subject"}],
+ [{xmlelement,"value",[],[{xmlcdata,S}]}]}]
+ end,
+ Announcement = case get_values("announcement", XData) of
+ [] -> [];
+ As -> [{xmlelement, "field", [{"var","body"}],
+ [{xmlelement,"value",[],[{xmlcdata,Line}]} || Line <- As] }]
+ end,
+ case Subject ++ Announcement of
+ [] -> ok;
+ SubEls ->
+ Request = #adhoc_request{
+ lang = "es",
+ node = ?NS_ADMINX("announce-online-allhosts"),
+ sessionid = "2007-08-17T15:28:40.517806Z",
+ action = "complete",
+ xdata = {xmlelement, "x",
+ [{"xmlns","jabber:x:data"},{"type","submit"}],
+ SubEls},
+ others= [{xmlelement, "x",
+ [{"xmlns","jabber:x:data"},{"type","submit"}],
+ SubEls}]
+ },
+ To = jlib:make_jid("", Host, ""),
+ mod_announce:announce_commands(empty, From, To, Request)
+ end,
+ Time = timer:seconds(Delay),
+ Node = list_to_atom(ENode),
+ {ok, _} = timer:apply_after(Time, rpc, call, [Node, init, Action, []]),
+ {result, []}.
+
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
adhoc_sm_commands(_Acc, From,
get_sm_form(User, Server, "config", Lang) ->
{result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}],
- [{xmlelement, "title", [],
+ [?HFIELD(),
+ {xmlelement, "title", [],
[{xmlcdata,
- translate:translate(
- Lang, "Administration of ") ++ User}]},
+ ?T(
+ Lang, "Administration of ") ++ User}]},
{xmlelement, "field",
[{"type", "list-single"},
- {"label", translate:translate(Lang, "Action on user")},
+ {"label", ?T(Lang, "Action on user")},
{"var", "action"}],
[{xmlelement, "value", [], [{xmlcdata, "edit"}]},
{xmlelement, "option",
- [{"label", translate:translate(Lang, "Edit Properties")}],
+ [{"label", ?T(Lang, "Edit Properties")}],
[{xmlelement, "value", [], [{xmlcdata, "edit"}]}]},
{xmlelement, "option",
- [{"label", translate:translate(Lang, "Remove User")}],
+ [{"label", ?T(Lang, "Remove User")}],
[{xmlelement, "value", [], [{xmlcdata, "remove"}]}]}
]},
?XFIELD("text-private", "Password", "password",
ejabberd_auth:get_password_s(User, Server))
- ]}]};
+ ]}]};
get_sm_form(_User, _Server, _Node, _Lang) ->
{error, ?ERR_SERVICE_UNAVAILABLE}.
set_sm_form(_User, _Server, _Node, _Request, _Fields) ->
{error, ?ERR_SERVICE_UNAVAILABLE}.
+
+