Skip to content

Commit 03e535e

Browse files
committed
mod_conversejs: Improve link to conversejs in WebAdmin (#4495)
Until now, the WebAdmin menu included a link to the first request handler with mod_conversejs that the admin configured in ejabberd.yml That link included the authentication credentials hashed as URI arguments if using HTTPS. Then process/2 extracted those arguments and passed them as autologin options to Converse. From now, mod_conversejs automatically adds a request_handler nested in webadmin subpath. The webadmin menu links to that converse URI; this allows to access the HTTP auth credentials, no need to explicitly pass them. process/2 extracts this HTTP auth and passes autologin options to Converse. Now scram password storage is supported too. This minimum configuration allows WebAdmin to access Converse: listen: - port: 5443 module: ejabberd_http tls: true request_handlers: /admin: ejabberd_web_admin /ws: ejabberd_http_ws modules: mod_conversejs: conversejs_resources: "/home/conversejs/12.0.0/dist"
1 parent c0de565 commit 03e535e

File tree

1 file changed

+37
-56
lines changed

1 file changed

+37
-56
lines changed

src/mod_conversejs.erl

Lines changed: 37 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -31,16 +31,19 @@
3131

3232
-export([start/2, stop/1, reload/3, process/2, depends/2,
3333
mod_opt_type/1, mod_options/1, mod_doc/0]).
34-
-export([web_menu_system/2]).
34+
-export([http_handlers_init/2, web_menu_system/3]).
3535

3636
-include_lib("xmpp/include/xmpp.hrl").
3737
-include("logger.hrl").
3838
-include("ejabberd_http.hrl").
3939
-include("translate.hrl").
4040
-include("ejabberd_web_admin.hrl").
4141

42+
-define(AUTOLOGIN_PATH, <<"conversejs-autologin">>).
43+
4244
start(_Host, _Opts) ->
43-
{ok, [{hook, webadmin_menu_system_post, web_menu_system, 50, global}]}.
45+
{ok, [{hook, http_request_handlers_init, http_handlers_init, 50, global},
46+
{hook, webadmin_menu_system_post, web_menu_system, 50, global}]}.
4447

4548
stop(_Host) ->
4649
ok.
@@ -51,10 +54,19 @@ reload(_Host, _NewOpts, _OldOpts) ->
5154
depends(_Host, _Opts) ->
5255
[].
5356

54-
process([], #request{method = 'GET', host = Host, q = Query, raw_path = RawPath1}) ->
57+
process(LocalPath, #request{auth = Auth, path = Path} = Request) ->
58+
AutologinPath = lists:member(?AUTOLOGIN_PATH, Path),
59+
case {AutologinPath, Auth} of
60+
{true, undefined} ->
61+
ejabberd_web:error(not_found);
62+
_ ->
63+
process2(LocalPath, Request)
64+
end.
65+
66+
process2([], #request{method = 'GET', host = Host, auth = Auth, raw_path = RawPath1}) ->
5567
[RawPath | _] = string:split(RawPath1, "?"),
5668
ExtraOptions = get_auth_options(Host)
57-
++ get_autologin_options(Query)
69+
++ get_autologin_options(Auth)
5870
++ get_register_options(Host)
5971
++ get_extra_options(Host),
6072
Domain = mod_conversejs_opt:default_domain(Host),
@@ -99,7 +111,7 @@ process([], #request{method = 'GET', host = Host, q = Query, raw_path = RawPath1
99111
<<"</script>">>,
100112
<<"</body>">>,
101113
<<"</html>">>]};
102-
process(LocalPath, #request{host = Host}) ->
114+
process2(LocalPath, #request{host = Host}) ->
103115
case is_served_file(LocalPath) of
104116
true -> serve(Host, LocalPath);
105117
false -> ejabberd_web:error(not_found)
@@ -181,6 +193,11 @@ get_auth_options(Domain) ->
181193
{<<"jid">>, Domain}]
182194
end.
183195

196+
get_autologin_options({Jid, Password}) ->
197+
[{<<"auto_login">>, <<"true">>}, {<<"jid">>, Jid}, {<<"password">>, Password}];
198+
get_autologin_options(undefined) ->
199+
[].
200+
184201
get_register_options(Server) ->
185202
AuthSupportsRegister =
186203
lists:any(
@@ -252,63 +269,27 @@ get_plugins_html(Host, RawPath) ->
252269

253270
%% @format-begin
254271

255-
web_menu_system(Result,
256-
#request{host = Host,
257-
auth = Auth,
258-
tp = Protocol}) ->
259-
AutoUrl = ejabberd_http:get_auto_url(any, ?MODULE),
260-
ConverseUrl = misc:expand_keyword(<<"@HOST@">>, AutoUrl, Host),
261-
AutologinQuery =
262-
case {Protocol, Auth} of
263-
{http, {Jid, _Password}} ->
264-
<<"/?autologinjid=", Jid/binary>>;
265-
{https, {Jid, Password}} ->
266-
AuthToken = build_token(Jid, Password),
267-
<<"/?autologinjid=", Jid/binary, "&autologintoken=", AuthToken/binary>>;
268-
_ ->
269-
<<"">>
270-
end,
272+
http_handlers_init(Handlers, _Opts) ->
273+
Handlers2 =
274+
lists:foldl(fun ({Path, ejabberd_web_admin} = Handler, Acc) ->
275+
[Handler, {lists:append(Path, [?AUTOLOGIN_PATH]), mod_conversejs}
276+
| Acc];
277+
(Handler, Acc) ->
278+
[Handler | Acc]
279+
end,
280+
[],
281+
Handlers),
282+
lists:reverse(Handlers2).
283+
284+
web_menu_system(Result, _Request, Level) ->
285+
Base = iolist_to_binary(lists:duplicate(Level, "../")),
271286
ConverseEl =
272287
?LI([?C(unicode:characters_to_binary("☯️")),
273288
?XAE(<<"a">>,
274-
[{<<"href">>, <<ConverseUrl/binary, AutologinQuery/binary>>},
289+
[{<<"href">>, <<Base/binary, ?AUTOLOGIN_PATH/binary>>},
275290
{<<"target">>, <<"_blank">>}],
276291
[?C(unicode:characters_to_binary("Converse"))])]),
277292
[ConverseEl | Result].
278-
279-
get_autologin_options(Query) ->
280-
case {proplists:get_value(<<"autologinjid">>, Query),
281-
proplists:get_value(<<"autologintoken">>, Query)}
282-
of
283-
{undefined, _} ->
284-
[];
285-
{Jid, Token} ->
286-
[{<<"auto_login">>, <<"true">>},
287-
{<<"jid">>, <<"admin@localhost">>},
288-
{<<"password">>, check_token_get_password(Jid, Token)}]
289-
end.
290-
291-
build_token(Jid, Password) ->
292-
Minutes =
293-
integer_to_binary(calendar:datetime_to_gregorian_seconds(
294-
calendar:universal_time())
295-
div 60),
296-
Cookie =
297-
misc:atom_to_binary(
298-
erlang:get_cookie()),
299-
str:sha(<<Jid/binary, Password/binary, Minutes/binary, Cookie/binary>>).
300-
301-
check_token_get_password(_, undefined) ->
302-
<<"">>;
303-
check_token_get_password(JidString, TokenProvided) ->
304-
Jid = jid:decode(JidString),
305-
Password = ejabberd_auth:get_password_s(Jid#jid.luser, Jid#jid.lserver),
306-
case build_token(JidString, Password) of
307-
TokenProvided ->
308-
Password;
309-
_ ->
310-
<<"">>
311-
end.
312293
%% @format-end
313294

314295
%%----------------------------------------------------------------------

0 commit comments

Comments
 (0)