25
1
mirror of https://github.com/processone/ejabberd.git synced 2024-12-26 17:38:45 +01:00

Support custom base path in WebAdmin by using relative URLs (#3043)

This commit is contained in:
Badlop 2019-10-02 11:54:22 +02:00
parent 7fc272918a
commit 20205c66c1
3 changed files with 93 additions and 73 deletions

View File

@ -95,20 +95,20 @@ get_jid(Auth, HostHTTP, Method) ->
throw({unauthorized, Auth}) throw({unauthorized, Auth})
end. end.
get_menu_items(global, cluster, Lang, JID) -> get_menu_items(global, cluster, Lang, JID, Level) ->
{Base, _, Items} = make_server_menu([], [], Lang, JID), {_Base, _, Items} = make_server_menu([], [], Lang, JID, Level),
lists:map(fun ({URI, Name}) -> lists:map(fun ({URI, Name}) ->
{<<Base/binary, URI/binary, "/">>, Name}; {<<URI/binary, "/">>, Name};
({URI, Name, _SubMenu}) -> ({URI, Name, _SubMenu}) ->
{<<Base/binary, URI/binary, "/">>, Name} {<<URI/binary, "/">>, Name}
end, end,
Items); Items);
get_menu_items(Host, cluster, Lang, JID) -> get_menu_items(Host, cluster, Lang, JID, Level) ->
{Base, _, Items} = make_host_menu(Host, [], Lang, JID), {_Base, _, Items} = make_host_menu(Host, [], Lang, JID, Level),
lists:map(fun ({URI, Name}) -> lists:map(fun ({URI, Name}) ->
{<<Base/binary, URI/binary, "/">>, Name}; {<<URI/binary, "/">>, Name};
({URI, Name, _SubMenu}) -> ({URI, Name, _SubMenu}) ->
{<<Base/binary, URI/binary, "/">>, Name} {<<URI/binary, "/">>, Name}
end, end,
Items). Items).
@ -290,16 +290,16 @@ get_auth_account2(HostOfRule, AccessRule, User, Server,
%%%================================== %%%==================================
%%%% make_xhtml %%%% make_xhtml
make_xhtml(Els, Host, Lang, JID) -> make_xhtml(Els, Host, Lang, JID, Level) ->
make_xhtml(Els, Host, cluster, Lang, JID). make_xhtml(Els, Host, cluster, Lang, JID, Level).
%% @spec (Els, Host, Node, Lang, JID) -> {200, [html], xmlelement()} %% @spec (Els, Host, Node, Lang, JID) -> {200, [html], xmlelement()}
%% where Host = global | string() %% where Host = global | string()
%% Node = cluster | atom() %% Node = cluster | atom()
%% JID = jid() %% JID = jid()
make_xhtml(Els, Host, Node, Lang, JID) -> make_xhtml(Els, Host, Node, Lang, JID, Level) ->
Base = get_base_path(Host, cluster), Base = get_base_path_sum(0, 0, Level),
MenuItems = make_navigation(Host, Node, Lang, JID), MenuItems = make_navigation(Host, Node, Lang, JID, Level),
{200, [html], {200, [html],
#xmlel{name = <<"html">>, #xmlel{name = <<"html">>,
attrs = attrs =
@ -339,7 +339,7 @@ make_xhtml(Els, Host, Node, Lang, JID) ->
[?XAE(<<"div">>, [{<<"id">>, <<"container">>}], [?XAE(<<"div">>, [{<<"id">>, <<"container">>}],
[?XAE(<<"div">>, [{<<"id">>, <<"header">>}], [?XAE(<<"div">>, [{<<"id">>, <<"header">>}],
[?XE(<<"h1">>, [?XE(<<"h1">>,
[?ACT(<<"/admin/">>, [?ACT(Base,
<<"ejabberd Web Admin">>)])]), <<"ejabberd Web Admin">>)])]),
?XAE(<<"div">>, [{<<"id">>, <<"navigation">>}], ?XAE(<<"div">>, [{<<"id">>, <<"navigation">>}],
[?XE(<<"ul">>, MenuItems)]), [?XE(<<"ul">>, MenuItems)]),
@ -357,15 +357,19 @@ make_xhtml(Els, Host, Node, Lang, JID) ->
direction(<<"he">>) -> [{<<"dir">>, <<"rtl">>}]; direction(<<"he">>) -> [{<<"dir">>, <<"rtl">>}];
direction(_) -> []. direction(_) -> [].
get_base_path(global, cluster) -> <<"/admin/">>; get_base_path(Host, Node, Level) ->
get_base_path(Host, cluster) -> SumHost = case Host of
<<"/admin/server/", Host/binary, "/">>; global -> 0;
get_base_path(global, Node) -> _ -> -2
<<"/admin/node/", end,
(iolist_to_binary(atom_to_list(Node)))/binary, "/">>; SumNode = case Node of
get_base_path(Host, Node) -> cluster -> 0;
<<"/admin/server/", Host/binary, "/node/", _ -> -2
(iolist_to_binary(atom_to_list(Node)))/binary, "/">>. end,
get_base_path_sum(SumHost, SumNode, Level).
get_base_path_sum(SumHost, SumNode, Level) ->
iolist_to_binary(lists:duplicate(Level + SumHost + SumNode, "../")).
%%%================================== %%%==================================
%%%% css & images %%%% css & images
@ -379,7 +383,7 @@ additions_js() ->
css(Host) -> css(Host) ->
case misc:read_css("admin.css") of case misc:read_css("admin.css") of
{ok, CSS} -> {ok, CSS} ->
Base = get_base_path(Host, cluster), Base = get_base_path(Host, cluster, 0),
re:replace(CSS, <<"@BASE@">>, Base, [{return, binary}]); re:replace(CSS, <<"@BASE@">>, Base, [{return, binary}]);
{error, _} -> {error, _} ->
<<>> <<>>
@ -413,15 +417,15 @@ process_admin(global, #request{path = [], lang = Lang}, AJID) ->
[?XE(<<"ul">>, [?XE(<<"ul">>,
[?LI([?ACT(MIU, MIN)]) [?LI([?ACT(MIU, MIN)])
|| {MIU, MIN} || {MIU, MIN}
<- get_menu_items(global, cluster, Lang, AJID)])], <- get_menu_items(global, cluster, Lang, AJID, 0)])],
global, Lang, AJID); global, Lang, AJID, 0);
process_admin(Host, #request{path = [], lang = Lang}, AJID) -> process_admin(Host, #request{path = [], lang = Lang}, AJID) ->
make_xhtml([?XCT(<<"h1">>, ?T("Administration")), make_xhtml([?XCT(<<"h1">>, ?T("Administration")),
?XE(<<"ul">>, ?XE(<<"ul">>,
[?LI([?ACT(MIU, MIN)]) [?LI([?ACT(MIU, MIN)])
|| {MIU, MIN} || {MIU, MIN}
<- get_menu_items(Host, cluster, Lang, AJID)])], <- get_menu_items(Host, cluster, Lang, AJID, 2)])],
Host, Lang, AJID); Host, Lang, AJID, 2);
process_admin(Host, #request{path = [<<"style.css">>]}, _) -> process_admin(Host, #request{path = [<<"style.css">>]}, _) ->
{200, {200,
[{<<"Content-Type">>, <<"text/css">>}, last_modified(), [{<<"Content-Type">>, <<"text/css">>}, last_modified(),
@ -452,26 +456,26 @@ process_admin(global, #request{path = [<<"vhosts">>], lang = Lang}, AJID) ->
make_xhtml((?H1GL((translate:translate(Lang, ?T("Virtual Hosts"))), make_xhtml((?H1GL((translate:translate(Lang, ?T("Virtual Hosts"))),
<<"virtual-hosting">>, ?T("Virtual Hosting"))) <<"virtual-hosting">>, ?T("Virtual Hosting")))
++ Res, ++ Res,
global, Lang, AJID); global, Lang, AJID, 1);
process_admin(Host, #request{path = [<<"users">>], q = Query, process_admin(Host, #request{path = [<<"users">>], q = Query,
lang = Lang}, AJID) lang = Lang}, AJID)
when is_binary(Host) -> when is_binary(Host) ->
Res = list_users(Host, Query, Lang, fun url_func/1), Res = list_users(Host, Query, Lang, fun url_func/1),
make_xhtml([?XCT(<<"h1">>, ?T("Users"))] ++ Res, Host, make_xhtml([?XCT(<<"h1">>, ?T("Users"))] ++ Res, Host,
Lang, AJID); Lang, AJID, 3);
process_admin(Host, #request{path = [<<"users">>, Diap], process_admin(Host, #request{path = [<<"users">>, Diap],
lang = Lang}, AJID) lang = Lang}, AJID)
when is_binary(Host) -> when is_binary(Host) ->
Res = list_users_in_diapason(Host, Diap, Lang, Res = list_users_in_diapason(Host, Diap, Lang,
fun url_func/1), fun url_func/1),
make_xhtml([?XCT(<<"h1">>, ?T("Users"))] ++ Res, Host, make_xhtml([?XCT(<<"h1">>, ?T("Users"))] ++ Res, Host,
Lang, AJID); Lang, AJID, 4);
process_admin(Host, #request{path = [<<"online-users">>], process_admin(Host, #request{path = [<<"online-users">>],
lang = Lang}, AJID) lang = Lang}, AJID)
when is_binary(Host) -> when is_binary(Host) ->
Res = list_online_users(Host, Lang), Res = list_online_users(Host, Lang),
make_xhtml([?XCT(<<"h1">>, ?T("Online Users"))] ++ Res, make_xhtml([?XCT(<<"h1">>, ?T("Online Users"))] ++ Res,
Host, Lang, AJID); Host, Lang, AJID, 3);
process_admin(Host, #request{path = [<<"last-activity">>], process_admin(Host, #request{path = [<<"last-activity">>],
q = Query, lang = Lang}, AJID) q = Query, lang = Lang}, AJID)
when is_binary(Host) -> when is_binary(Host) ->
@ -513,33 +517,45 @@ process_admin(Host, #request{path = [<<"last-activity">>],
?INPUTT(<<"submit">>, <<"integral">>, ?INPUTT(<<"submit">>, <<"integral">>,
?T("Show Integral Table"))])] ?T("Show Integral Table"))])]
++ Res, ++ Res,
Host, Lang, AJID); Host, Lang, AJID, 3);
process_admin(Host, #request{path = [<<"stats">>], lang = Lang}, AJID) -> process_admin(Host, #request{path = [<<"stats">>], lang = Lang}, AJID) ->
Res = get_stats(Host, Lang), Res = get_stats(Host, Lang),
PageH1 = ?H1GL(translate:translate(Lang, ?T("Statistics")), <<"mod-stats">>, <<"mod_stats">>), PageH1 = ?H1GL(translate:translate(Lang, ?T("Statistics")), <<"mod-stats">>, <<"mod_stats">>),
make_xhtml(PageH1 ++ Res, Host, Lang, AJID); Level = case Host of
global -> 1;
_ -> 3
end,
make_xhtml(PageH1 ++ Res, Host, Lang, AJID, Level);
process_admin(Host, #request{path = [<<"user">>, U], process_admin(Host, #request{path = [<<"user">>, U],
q = Query, lang = Lang}, AJID) -> q = Query, lang = Lang}, AJID) ->
case ejabberd_auth:user_exists(U, Host) of case ejabberd_auth:user_exists(U, Host) of
true -> true ->
Res = user_info(U, Host, Query, Lang), Res = user_info(U, Host, Query, Lang),
make_xhtml(Res, Host, Lang, AJID); make_xhtml(Res, Host, Lang, AJID, 4);
false -> false ->
make_xhtml([?XCT(<<"h1">>, ?T("Not Found"))], Host, make_xhtml([?XCT(<<"h1">>, ?T("Not Found"))], Host,
Lang, AJID) Lang, AJID, 4)
end; end;
process_admin(Host, #request{path = [<<"nodes">>], lang = Lang}, AJID) -> process_admin(Host, #request{path = [<<"nodes">>], lang = Lang}, AJID) ->
Res = get_nodes(Lang), Res = get_nodes(Lang),
make_xhtml(Res, Host, Lang, AJID); Level = case Host of
global -> 1;
_ -> 3
end,
make_xhtml(Res, Host, Lang, AJID, Level);
process_admin(Host, #request{path = [<<"node">>, SNode | NPath], process_admin(Host, #request{path = [<<"node">>, SNode | NPath],
q = Query, lang = Lang}, AJID) -> q = Query, lang = Lang}, AJID) ->
case search_running_node(SNode) of case search_running_node(SNode) of
false -> false ->
make_xhtml([?XCT(<<"h1">>, ?T("Node not found"))], Host, make_xhtml([?XCT(<<"h1">>, ?T("Node not found"))], Host,
Lang, AJID); Lang, AJID, 2);
Node -> Node ->
Res = get_node(Host, Node, NPath, Query, Lang), Res = get_node(Host, Node, NPath, Query, Lang),
make_xhtml(Res, Host, Node, Lang, AJID) Level = case Host of
global -> 2 + length(NPath);
_ -> 4 + length(NPath)
end,
make_xhtml(Res, Host, Node, Lang, AJID, Level)
end; end;
%%%================================== %%%==================================
%%%% process_admin default case %%%% process_admin default case
@ -552,13 +568,17 @@ process_admin(Host, #request{lang = Lang} = Request, AJID) ->
ejabberd_hooks:run_fold( ejabberd_hooks:run_fold(
webadmin_page_host, Host, [], [Host, Request]) webadmin_page_host, Host, [], [Host, Request])
end, end,
Level = case Host of
global -> length(Request#request.path);
_ -> 2 + length(Request#request.path)
end,
case Res of case Res of
[] -> [] ->
setelement(1, setelement(1,
make_xhtml([?XC(<<"h1">>, <<"Not Found">>)], Host, Lang, make_xhtml([?XC(<<"h1">>, <<"Not Found">>)], Host, Lang,
AJID), AJID, Level),
404); 404);
_ -> make_xhtml(Res, Host, Lang, AJID) _ -> make_xhtml(Res, Host, Lang, AJID, Level)
end. end.
term_to_id(T) -> base64:encode((term_to_binary(T))). term_to_id(T) -> base64:encode((term_to_binary(T))).
@ -1081,7 +1101,7 @@ search_running_node(SNode, [Node | Nodes]) ->
get_node(global, Node, [], Query, Lang) -> get_node(global, Node, [], Query, Lang) ->
Res = node_parse_query(Node, Query), Res = node_parse_query(Node, Query),
Base = get_base_path(global, Node), Base = get_base_path(global, Node, 2),
MenuItems2 = make_menu_items(global, Node, Base, Lang), MenuItems2 = make_menu_items(global, Node, Base, Lang),
[?XC(<<"h1">>, [?XC(<<"h1">>,
(str:format(translate:translate(Lang, ?T("Node ~p")), [Node])))] (str:format(translate:translate(Lang, ?T("Node ~p")), [Node])))]
@ -1093,10 +1113,10 @@ get_node(global, Node, [], Query, Lang) ->
end end
++ ++
[?XE(<<"ul">>, [?XE(<<"ul">>,
([?LI([?ACT(<<Base/binary, "db/">>, ?T("Database"))]), ([?LI([?ACT(<<"db/">>, ?T("Database"))]),
?LI([?ACT(<<Base/binary, "backup/">>, ?T("Backup"))]), ?LI([?ACT(<<"backup/">>, ?T("Backup"))]),
?LI([?ACT(<<Base/binary, "stats/">>, ?T("Statistics"))]), ?LI([?ACT(<<"stats/">>, ?T("Statistics"))]),
?LI([?ACT(<<Base/binary, "update/">>, ?T("Update"))])] ?LI([?ACT(<<"update/">>, ?T("Update"))])]
++ MenuItems2)), ++ MenuItems2)),
?XAE(<<"form">>, ?XAE(<<"form">>,
[{<<"action">>, <<"">>}, {<<"method">>, <<"post">>}], [{<<"action">>, <<"">>}, {<<"method">>, <<"post">>}],
@ -1104,7 +1124,7 @@ get_node(global, Node, [], Query, Lang) ->
?C(<<" ">>), ?C(<<" ">>),
?INPUTT(<<"submit">>, <<"stop">>, ?T("Stop"))])]; ?INPUTT(<<"submit">>, <<"stop">>, ?T("Stop"))])];
get_node(Host, Node, [], _Query, Lang) -> get_node(Host, Node, [], _Query, Lang) ->
Base = get_base_path(Host, Node), Base = get_base_path(Host, Node, 4),
MenuItems2 = make_menu_items(Host, Node, Base, Lang), MenuItems2 = make_menu_items(Host, Node, Base, Lang),
[?XC(<<"h1">>, (str:format(translate:translate(Lang, ?T("Node ~p")), [Node]))), [?XC(<<"h1">>, (str:format(translate:translate(Lang, ?T("Node ~p")), [Node]))),
?XE(<<"ul">>, MenuItems2)]; ?XE(<<"ul">>, MenuItems2)];
@ -1733,8 +1753,8 @@ pretty_string_int(String) when is_binary(String) ->
%%%% navigation menu %%%% navigation menu
%% @spec (Host, Node, Lang, JID::jid()) -> [LI] %% @spec (Host, Node, Lang, JID::jid()) -> [LI]
make_navigation(Host, Node, Lang, JID) -> make_navigation(Host, Node, Lang, JID, Level) ->
Menu = make_navigation_menu(Host, Node, Lang, JID), Menu = make_navigation_menu(Host, Node, Lang, JID, Level),
make_menu_items(Lang, Menu). make_menu_items(Lang, Menu).
%% @spec (Host, Node, Lang, JID::jid()) -> Menu %% @spec (Host, Node, Lang, JID::jid()) -> Menu
@ -1744,13 +1764,13 @@ make_navigation(Host, Node, Lang, JID) ->
%% Menu = {URL, Title} | {URL, Title, [Menu]} %% Menu = {URL, Title} | {URL, Title, [Menu]}
%% URL = string() %% URL = string()
%% Title = string() %% Title = string()
make_navigation_menu(Host, Node, Lang, JID) -> make_navigation_menu(Host, Node, Lang, JID, Level) ->
HostNodeMenu = make_host_node_menu(Host, Node, Lang, HostNodeMenu = make_host_node_menu(Host, Node, Lang,
JID), JID, Level),
HostMenu = make_host_menu(Host, HostNodeMenu, Lang, HostMenu = make_host_menu(Host, HostNodeMenu, Lang,
JID), JID, Level),
NodeMenu = make_node_menu(Host, Node, Lang), NodeMenu = make_node_menu(Host, Node, Lang, Level),
make_server_menu(HostMenu, NodeMenu, Lang, JID). make_server_menu(HostMenu, NodeMenu, Lang, JID, Level).
%% @spec (Host, Node, Base, Lang) -> [LI] %% @spec (Host, Node, Base, Lang) -> [LI]
make_menu_items(global, cluster, Base, Lang) -> make_menu_items(global, cluster, Base, Lang) ->
@ -1767,12 +1787,12 @@ make_menu_items(Host, Node, Base, Lang) ->
Lang), Lang),
make_menu_items(Lang, {Base, <<"">>, HookItems}). make_menu_items(Lang, {Base, <<"">>, HookItems}).
make_host_node_menu(global, _, _Lang, _JID) -> make_host_node_menu(global, _, _Lang, _JID, _Level) ->
{<<"">>, <<"">>, []}; {<<"">>, <<"">>, []};
make_host_node_menu(_, cluster, _Lang, _JID) -> make_host_node_menu(_, cluster, _Lang, _JID, _Level) ->
{<<"">>, <<"">>, []}; {<<"">>, <<"">>, []};
make_host_node_menu(Host, Node, Lang, JID) -> make_host_node_menu(Host, Node, Lang, JID, Level) ->
HostNodeBase = get_base_path(Host, Node), HostNodeBase = get_base_path(Host, Node, Level),
HostNodeFixed = get_menu_items_hook({hostnode, Host, Node}, Lang), HostNodeFixed = get_menu_items_hook({hostnode, Host, Node}, Lang),
HostNodeBasePath = url_to_path(HostNodeBase), HostNodeBasePath = url_to_path(HostNodeBase),
HostNodeFixed2 = [Tuple HostNodeFixed2 = [Tuple
@ -1781,10 +1801,10 @@ make_host_node_menu(Host, Node, Lang, JID) ->
{HostNodeBase, iolist_to_binary(atom_to_list(Node)), {HostNodeBase, iolist_to_binary(atom_to_list(Node)),
HostNodeFixed2}. HostNodeFixed2}.
make_host_menu(global, _HostNodeMenu, _Lang, _JID) -> make_host_menu(global, _HostNodeMenu, _Lang, _JID, _Level) ->
{<<"">>, <<"">>, []}; {<<"">>, <<"">>, []};
make_host_menu(Host, HostNodeMenu, Lang, JID) -> make_host_menu(Host, HostNodeMenu, Lang, JID, Level) ->
HostBase = get_base_path(Host, cluster), HostBase = get_base_path(Host, cluster, Level),
HostFixed = [{<<"users">>, ?T("Users")}, HostFixed = [{<<"users">>, ?T("Users")},
{<<"online-users">>, ?T("Online Users")}] {<<"online-users">>, ?T("Online Users")}]
++ ++
@ -1798,22 +1818,22 @@ make_host_menu(Host, HostNodeMenu, Lang, JID) ->
is_allowed_path(HostBasePath, Tuple, JID)], is_allowed_path(HostBasePath, Tuple, JID)],
{HostBase, Host, HostFixed2}. {HostBase, Host, HostFixed2}.
make_node_menu(_Host, cluster, _Lang) -> make_node_menu(_Host, cluster, _Lang, _Level) ->
{<<"">>, <<"">>, []}; {<<"">>, <<"">>, []};
make_node_menu(global, Node, Lang) -> make_node_menu(global, Node, Lang, Level) ->
NodeBase = get_base_path(global, Node), NodeBase = get_base_path(global, Node, Level),
NodeFixed = [{<<"db/">>, ?T("Database")}, NodeFixed = [{<<"db">>, ?T("Database")},
{<<"backup/">>, ?T("Backup")}, {<<"backup">>, ?T("Backup")},
{<<"stats/">>, ?T("Statistics")}, {<<"stats">>, ?T("Statistics")},
{<<"update/">>, ?T("Update")}] {<<"update">>, ?T("Update")}]
++ get_menu_items_hook({node, Node}, Lang), ++ get_menu_items_hook({node, Node}, Lang),
{NodeBase, iolist_to_binary(atom_to_list(Node)), {NodeBase, iolist_to_binary(atom_to_list(Node)),
NodeFixed}; NodeFixed};
make_node_menu(_Host, _Node, _Lang) -> make_node_menu(_Host, _Node, _Lang, _Level) ->
{<<"">>, <<"">>, []}. {<<"">>, <<"">>, []}.
make_server_menu(HostMenu, NodeMenu, Lang, JID) -> make_server_menu(HostMenu, NodeMenu, Lang, JID, Level) ->
Base = get_base_path(global, cluster), Base = get_base_path(global, cluster, Level),
Fixed = [{<<"vhosts">>, ?T("Virtual Hosts"), HostMenu}, Fixed = [{<<"vhosts">>, ?T("Virtual Hosts"), HostMenu},
{<<"nodes">>, ?T("Nodes"), NodeMenu}, {<<"nodes">>, ?T("Nodes"), NodeMenu},
{<<"stats">>, ?T("Statistics")}] {<<"stats">>, ?T("Statistics")}]

View File

@ -465,7 +465,7 @@ web_page_main(_, #request{path=[<<"muc">>], lang = Lang} = _Request) ->
[?XE(<<"tbody">>, [?TDTD(?T("Total rooms"), OnlineRoomsNumber) [?XE(<<"tbody">>, [?TDTD(?T("Total rooms"), OnlineRoomsNumber)
]) ])
]), ]),
?XE(<<"ul">>, [?LI([?ACT(<<"rooms">>, ?T("List of rooms"))])]) ?XE(<<"ul">>, [?LI([?ACT(<<"rooms/">>, ?T("List of rooms"))])])
], ],
{stop, Res}; {stop, Res};

View File

@ -1031,7 +1031,7 @@ build_contact_jid_td(RosterJID) ->
case lists:member(CServer, ejabberd_option:hosts()) of case lists:member(CServer, ejabberd_option:hosts()) of
false -> <<"">>; false -> <<"">>;
true -> true ->
<<"/admin/server/", CServer/binary, "/user/", <<"../../../../../server/", CServer/binary, "/user/",
CUser/binary, "/">> CUser/binary, "/">>
end end
end, end,