Update some modules to work with ejabberd 19.08 (#277)
This commit is contained in:
parent
4753268b5f
commit
857d350a71
|
@ -1,6 +1,7 @@
|
|||
|
||||
mod_cron - Execute scheduled commands
|
||||
|
||||
Requires: ejabberd 19.08 or higher
|
||||
http://www.ejabberd.im/mod_cron
|
||||
Author: Badlop
|
||||
|
||||
|
|
|
@ -11,19 +11,18 @@
|
|||
|
||||
-behaviour(gen_mod).
|
||||
|
||||
-export([
|
||||
cron_list/1, cron_del/1,
|
||||
-export([start/2, stop/1, depends/2, mod_options/1, mod_opt_type/1]).
|
||||
-export([cron_list/1, cron_del/1,
|
||||
run_task/3,
|
||||
web_menu_host/3, web_page_host/3,
|
||||
start/2,
|
||||
apply_interval/3,
|
||||
apply_interval1/3,
|
||||
stop/1]).
|
||||
apply_interval1/3]).
|
||||
|
||||
-include("ejabberd_commands.hrl").
|
||||
-include("ejabberd_http.hrl").
|
||||
-include("ejabberd_web_admin.hrl").
|
||||
-include("logger.hrl").
|
||||
-include("translate.hrl").
|
||||
-include("xmpp.hrl").
|
||||
|
||||
-record(task, {taskid, timerref, host, task}).
|
||||
|
@ -36,7 +35,7 @@ start(Host, Opts) ->
|
|||
ejabberd_commands:register_commands(commands()),
|
||||
ejabberd_hooks:add(webadmin_menu_host, Host, ?MODULE, web_menu_host, 50),
|
||||
ejabberd_hooks:add(webadmin_page_host, Host, ?MODULE, web_page_host, 50),
|
||||
Tasks = gen_mod:get_opt(tasks, Opts, []),
|
||||
Tasks = gen_mod:get_opt(tasks, Opts),
|
||||
catch ets:new(cron_tasks, [ordered_set, named_table, public, {keypos, 2}]),
|
||||
[add_task(Host, Task) || Task <- Tasks],
|
||||
ok.
|
||||
|
@ -49,6 +48,14 @@ stop(Host) ->
|
|||
[delete_task(Task) || Task <- get_tasks(Host)],
|
||||
ok.
|
||||
|
||||
depends(_Host, _Opts) ->
|
||||
[].
|
||||
|
||||
mod_opt_type(tasks) ->
|
||||
econf:list(econf:any()).
|
||||
|
||||
mod_options(_Host) ->
|
||||
[{tasks, []}].
|
||||
|
||||
%% ---------------------
|
||||
%% Task management
|
||||
|
@ -231,7 +238,7 @@ cron_del(TaskId) ->
|
|||
%% ---------------------
|
||||
|
||||
web_menu_host(Acc, _Host, Lang) ->
|
||||
[{<<"cron">>, ?T(<<"Cron Tasks">>)} | Acc].
|
||||
[{<<"cron">>, translate:translate(Lang, ?T("Cron Tasks"))} | Acc].
|
||||
|
||||
web_page_host(_, Host,
|
||||
#request{path = [<<"cron">>],
|
||||
|
@ -245,9 +252,13 @@ web_page_host(Acc, _, _) -> Acc.
|
|||
make_tasks_table(Tasks, Lang) ->
|
||||
TList = lists:map(
|
||||
fun(T) ->
|
||||
{Time_num, Time_unit, Mod, Fun, Args} = T#task.task,
|
||||
[TimeNum, TimeUnit, Mod, Fun, Args, InTimerType] =
|
||||
[proplists:get_value(Key, T#task.task)
|
||||
|| Key <- [time, units, module, function, arguments, timer_type]],
|
||||
?XE(<<"tr">>,
|
||||
[?XC(<<"td">>, list_to_binary(integer_to_list(Time_num) ++" " ++ atom_to_list(Time_unit))),
|
||||
[?XC(<<"td">>, list_to_binary(integer_to_list(TimeNum)++" "
|
||||
++atom_to_list(TimeUnit)++" "
|
||||
++atom_to_list(InTimerType))),
|
||||
?XC(<<"td">>, list_to_binary(atom_to_list(Mod))),
|
||||
?XC(<<"td">>, list_to_binary(atom_to_list(Fun))),
|
||||
?XC(<<"td">>, list_to_binary(io_lib:format("~p", [Args])))])
|
||||
|
|
|
@ -10,13 +10,10 @@
|
|||
|
||||
-behaviour(gen_mod).
|
||||
|
||||
-export([start/2,
|
||||
init/1,
|
||||
stop/1,
|
||||
depends/2,
|
||||
-export([start/2, stop/1, depends/2, mod_opt_type/1, mod_options/1]).
|
||||
-export([init/1,
|
||||
log_packet_send/1,
|
||||
log_packet_receive/1,
|
||||
mod_opt_type/1]).
|
||||
log_packet_receive/1]).
|
||||
|
||||
-ifndef(LAGER).
|
||||
-define(LAGER, 1).
|
||||
|
@ -33,7 +30,7 @@
|
|||
|
||||
start(Host, Opts) ->
|
||||
?DEBUG(" ~p ~p~n", [Host, Opts]),
|
||||
case gen_mod:get_opt(host_config, Opts, []) of
|
||||
case gen_mod:get_opt(host_config, Opts) of
|
||||
[] ->
|
||||
start_vh(Host, Opts);
|
||||
HostConfig ->
|
||||
|
@ -51,8 +48,8 @@ start_vhs(Host, [{_VHost, _Opts}| Tail]) ->
|
|||
?DEBUG("start_vhs ~p ~p~n", [Host, [{_VHost, _Opts}| Tail]]),
|
||||
start_vhs(Host, Tail).
|
||||
start_vh(Host, Opts) ->
|
||||
Path = gen_mod:get_opt(path, Opts, ?DEFAULT_PATH),
|
||||
Format = gen_mod:get_opt(format, Opts, ?DEFAULT_FORMAT),
|
||||
Path = gen_mod:get_opt(path, Opts),
|
||||
Format = gen_mod:get_opt(format, Opts),
|
||||
ejabberd_hooks:add(user_send_packet, Host, ?MODULE, log_packet_send, 55),
|
||||
ejabberd_hooks:add(user_receive_packet, Host, ?MODULE, log_packet_receive, 55),
|
||||
register(gen_mod:get_module_proc(Host, ?PROCNAME),
|
||||
|
@ -79,10 +76,6 @@ stop(Host) ->
|
|||
gen_mod:get_module_proc(Host, ?PROCNAME) ! stop,
|
||||
ok.
|
||||
|
||||
-spec depends(binary(), gen_mod:opts()) -> [{module(), hard | soft}].
|
||||
depends(_Host, _Opts) ->
|
||||
[].
|
||||
|
||||
log_packet_send({Packet, C2SState}) ->
|
||||
From = xmpp:get_from(Packet),
|
||||
To = xmpp:get_to(Packet),
|
||||
|
@ -103,10 +96,10 @@ log_packet_receive({Packet, C2SState}) ->
|
|||
|
||||
log_packet(From, To, #message{type = Type} = Packet, Host) ->
|
||||
case Type of
|
||||
<<"groupchat">> -> %% mod_muc_log already does it
|
||||
groupchat -> %% mod_muc_log already does it
|
||||
?DEBUG("dropping groupchat: ~s", [fxml:element_to_binary(Packet)]),
|
||||
ok;
|
||||
<<"error">> -> %% we don't log errors
|
||||
error -> %% we don't log errors
|
||||
?DEBUG("dropping error: ~s", [fxml:element_to_binary(Packet)]),
|
||||
ok;
|
||||
_ ->
|
||||
|
@ -286,8 +279,15 @@ css() ->
|
|||
".messagetext {color: black; margin: 0.2em; clear: both; display: block;}~n"++
|
||||
"//-->~n</style>~n".
|
||||
|
||||
depends(_Host, _Opts) ->
|
||||
[].
|
||||
|
||||
mod_opt_type(host_config) -> econf:list(econf:any());
|
||||
mod_opt_type(path) -> fun iolist_to_binary/1;
|
||||
mod_opt_type(format) ->
|
||||
fun (A) when is_atom(A) -> A end;
|
||||
mod_opt_type(_) ->
|
||||
[path, format].
|
||||
fun (A) when is_atom(A) -> A end.
|
||||
|
||||
mod_options(_Host) ->
|
||||
[{host_config, []},
|
||||
{path, ?DEFAULT_PATH},
|
||||
{format, ?DEFAULT_FORMAT}].
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
|
||||
mod_logsession - Log session connections to file
|
||||
|
||||
Requirements: ejabberd 19.08 or higher
|
||||
Homepage: http://www.ejabberd.im/mod_logsession
|
||||
Author: Badlop
|
||||
Requirements: ejabberd 17.01 or newer
|
||||
|
||||
|
||||
DESCRIPTION
|
||||
|
|
|
@ -29,14 +29,11 @@
|
|||
|
||||
-behaviour(gen_mod).
|
||||
|
||||
-export([
|
||||
start/2,
|
||||
stop/1,
|
||||
loop/3,
|
||||
-export([start/2, stop/1, depends/2, mod_options/1, mod_opt_type/1]).
|
||||
-export([loop/3,
|
||||
reopen_log/1,
|
||||
failed_auth/3,
|
||||
forbidden/1
|
||||
]).
|
||||
forbidden/1]).
|
||||
|
||||
-include("xmpp.hrl").
|
||||
-include("ejabberd_commands.hrl").
|
||||
|
@ -54,9 +51,7 @@ start(Host, Opts) ->
|
|||
ejabberd_commands:register_commands(commands()),
|
||||
Filename1 = gen_mod:get_opt(
|
||||
sessionlog,
|
||||
Opts,
|
||||
fun(S) -> S end,
|
||||
"/tmp/ejabberd_logsession_@HOST@.log"),
|
||||
Opts),
|
||||
Filename = replace_host(Host, Filename1),
|
||||
File = open_file(Filename),
|
||||
register(get_process_name(Host), spawn(?MODULE, loop, [Filename, File, Host])),
|
||||
|
@ -70,6 +65,15 @@ stop(Host) ->
|
|||
exit(whereis(Proc), stop),
|
||||
{wait, Proc}.
|
||||
|
||||
depends(_Host, _Opts) ->
|
||||
[].
|
||||
|
||||
mod_opt_type(sessionlog) ->
|
||||
econf:string().
|
||||
|
||||
mod_options(_Host) ->
|
||||
[{sessionlog, "/tmp/ejabberd_logsession_@HOST@.log"}].
|
||||
|
||||
%%%----------------------------------------------------------------------
|
||||
%%% REQUEST HANDLERS
|
||||
%%%----------------------------------------------------------------------
|
||||
|
@ -83,8 +87,8 @@ forbidden(JID) ->
|
|||
|
||||
failed_auth(State, true, _) ->
|
||||
State;
|
||||
failed_auth(#{lserver := Host, ip := IPPT} = State, false, U) ->
|
||||
get_process_name(Host) ! {log, {failed_auth, U, IPPT}},
|
||||
failed_auth(#{lserver := Host, ip := IPPT} = State, {false, Reason}, U) ->
|
||||
get_process_name(Host) ! {log, {failed_auth, U, IPPT, Reason}},
|
||||
State.
|
||||
|
||||
commands() ->
|
||||
|
@ -144,10 +148,10 @@ make_date(Date) ->
|
|||
io_lib:format("~w-~.2.0w-~.2.0w ~.2.0w:~.2.0w:~.2.0w",
|
||||
[Y, Mo, D, H, Mi, S]).
|
||||
|
||||
make_message(Host, {failed_auth, Username, {IPTuple, IPPort}}) ->
|
||||
make_message(Host, {failed_auth, Username, {IPTuple, IPPort}, Reason}) ->
|
||||
IPString = inet_parse:ntoa(IPTuple),
|
||||
io_lib:format("Failed authentication for ~s@~s from ~s port ~p",
|
||||
[Username, Host, IPString, IPPort]);
|
||||
io_lib:format("Failed authentication for ~s@~s from ~s port ~p: ~s",
|
||||
[Username, Host, IPString, IPPort, Reason]);
|
||||
make_message(_Host, {forbidden, JID}) ->
|
||||
io_lib:format("Forbidden session for ~s",
|
||||
[jlib:jid_to_string(JID)]).
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
Homepage: http://www.ejabberd.im/mod_logxml
|
||||
Author: Badlop
|
||||
Module for ejabberd git master
|
||||
Requires: ejabberd 19.08 or higher
|
||||
|
||||
|
||||
DESCRIPTION
|
||||
|
@ -38,15 +38,15 @@ show_ip:
|
|||
Default value: false
|
||||
rotate_days:
|
||||
Rotate logs every X days
|
||||
Put 'no' to disable this limit.
|
||||
Put 0 to disable this limit.
|
||||
Default value: 1
|
||||
rotate_megs:
|
||||
Rotate when the logfile size is higher than this, in megabytes.
|
||||
Put 'no' to disable this limit.
|
||||
Put 0 to disable this limit.
|
||||
Default value: 10
|
||||
rotate_kpackets:
|
||||
Rotate every *1000 XMPP packets logged
|
||||
Put 'no' to disable this limit.
|
||||
Put 0 to disable this limit.
|
||||
Default value: 10
|
||||
check_rotate_kpackets:
|
||||
Check rotation every *1000 packets
|
||||
|
@ -72,7 +72,7 @@ modules:
|
|||
show_ip: false
|
||||
rotate_days: 1
|
||||
rotate_megs: 100
|
||||
rotate_kpackets: no
|
||||
rotate_kpackets: 0
|
||||
check_rotate_kpackets: 1
|
||||
|
||||
|
||||
|
|
|
@ -12,5 +12,5 @@ modules:
|
|||
show_ip: false
|
||||
rotate_days: 1
|
||||
rotate_megs: 100
|
||||
rotate_kpackets: no
|
||||
rotate_kpackets: 0
|
||||
check_rotate_kpackets: 1
|
||||
|
|
|
@ -26,13 +26,16 @@
|
|||
start(Host, Opts) ->
|
||||
Logdir = gen_mod:get_opt(logdir, Opts),
|
||||
|
||||
Rd = gen_mod:get_opt(rotate_days, Opts),
|
||||
Rd = case gen_mod:get_opt(rotate_days, Opts) of
|
||||
0 -> no;
|
||||
Rd1 -> Rd1
|
||||
end,
|
||||
Rf = case gen_mod:get_opt(rotate_megs, Opts) of
|
||||
no -> no;
|
||||
0 -> no;
|
||||
Rf1 -> Rf1*1024*1024
|
||||
end,
|
||||
Rp = case gen_mod:get_opt(rotate_kpackets, Opts) of
|
||||
no -> no;
|
||||
0 -> no;
|
||||
Rp1 -> Rp1*1000
|
||||
end,
|
||||
RotateO = {Rd, Rf, Rp},
|
||||
|
@ -111,7 +114,7 @@ filter(FilterO, E) ->
|
|||
FilterO,
|
||||
{Orientation, From, To, Packet} = E,
|
||||
Stanza = element(1, Packet),
|
||||
Hosts_all = ejabberd_config:get_global_option(hosts, fun(A) -> A end),
|
||||
Hosts_all = ejabberd_config:get_option(hosts),
|
||||
{Host_local, Host_remote} = case Orientation of
|
||||
send -> {From#jid.lserver, To#jid.lserver};
|
||||
recv -> {To#jid.lserver, From#jid.lserver}
|
||||
|
@ -267,29 +270,23 @@ calc_div(_A, _B) ->
|
|||
0.5. %% This ensures that no rotation is performed
|
||||
|
||||
mod_opt_type(stanza) ->
|
||||
fun (L) when is_list(L) -> [] = L -- [iq, message, presence, other], L end;
|
||||
econf:list(econf:enum([iq, message, presence, other]));
|
||||
mod_opt_type(direction) ->
|
||||
fun (L) when is_list(L) -> [] = L -- [internal, vhosts, external], L end;
|
||||
econf:list(econf:enum([internal, vhosts, external]));
|
||||
mod_opt_type(orientation) ->
|
||||
fun (L) when is_list(L) -> [] = L -- [send, recv], L end;
|
||||
econf:list(econf:enum([send, recv]));
|
||||
mod_opt_type(logdir) ->
|
||||
fun iolist_to_binary/1;
|
||||
econf:directory();
|
||||
mod_opt_type(show_ip) ->
|
||||
fun (A) when is_boolean(A) -> A end;
|
||||
econf:bool();
|
||||
mod_opt_type(rotate_days) ->
|
||||
fun (I) when is_integer(I), I > 0 -> I;
|
||||
(no) -> no
|
||||
end;
|
||||
econf:non_neg_int();
|
||||
mod_opt_type(rotate_megs) ->
|
||||
fun (I) when is_integer(I), I > 0 -> I;
|
||||
(no) -> no
|
||||
end;
|
||||
econf:non_neg_int();
|
||||
mod_opt_type(rotate_kpackets) ->
|
||||
fun (I) when is_integer(I), I > 0 -> I;
|
||||
(no) -> no
|
||||
end;
|
||||
econf:non_neg_int();
|
||||
mod_opt_type(check_rotate_kpackets) ->
|
||||
fun (I) when is_integer(I), I > 0 -> I end.
|
||||
econf:non_neg_int().
|
||||
|
||||
mod_options(_Host) ->
|
||||
[{stanza, [iq, message, presence, other]},
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
mod_muc_log_http - Serve MUC logs on the web
|
||||
|
||||
Requires: ejabberd 19.08 or higher
|
||||
Homepage: http://ejabberd.im/mod_muc_log_http
|
||||
Author: Badlop
|
||||
|
||||
|
|
|
@ -10,11 +10,9 @@
|
|||
|
||||
-behaviour(gen_mod).
|
||||
|
||||
-export([
|
||||
start/2,
|
||||
stop/1,
|
||||
process/2
|
||||
]).
|
||||
-export([start/2, stop/1, depends/2, mod_options/1]).
|
||||
|
||||
-export([process/2]).
|
||||
|
||||
-include("xmpp.hrl").
|
||||
-include("ejabberd_http.hrl").
|
||||
|
@ -38,7 +36,7 @@ process(LocalPath, Request) ->
|
|||
serve(LocalPath, Request).
|
||||
|
||||
serve(LocalPathBin, #request{host = Host} = Request) ->
|
||||
DocRoot = binary_to_list(gen_mod:get_module_opt(Host, mod_muc_log, outdir, <<"www/muc">>)),
|
||||
DocRoot = binary_to_list(gen_mod:get_module_opt(Host, mod_muc_log, outdir)),
|
||||
LocalPath = [binary_to_list(LPB) || LPB <- LocalPathBin],
|
||||
FileName = filename:join(filename:split(DocRoot) ++ LocalPath),
|
||||
case file:read_file(FileName) of
|
||||
|
@ -230,3 +228,9 @@ start(_Host, _Opts) ->
|
|||
|
||||
stop(_Host) ->
|
||||
ok.
|
||||
|
||||
depends(_Host, _Opts) ->
|
||||
[{mod_muc_log, hard}].
|
||||
|
||||
mod_options(_Host) ->
|
||||
[].
|
||||
|
|
|
@ -60,9 +60,9 @@ filterMessageText2(Lang, MessageText) ->
|
|||
string:join(filterWords(MessageTerms), " ").
|
||||
|
||||
start(_Host, Opts) ->
|
||||
Blacklists = gen_mod:get_opt(blacklists, Opts, fun(A) -> A end, []),
|
||||
Blacklists = gen_mod:get_opt(blacklists, Opts),
|
||||
lists:map(fun bloom_gen_server:start/1, Blacklists),
|
||||
CharMaps = gen_mod:get_opt(charmaps, Opts, fun(A) -> A end, []),
|
||||
CharMaps = gen_mod:get_opt(charmaps, Opts),
|
||||
lists:map(fun normalize_leet_gen_server:start/1, CharMaps),
|
||||
ejabberd_hooks:add(filter_packet, global, ?MODULE, on_filter_packet, 0),
|
||||
ok.
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
|
||||
mod_rest - HTTP interface to POST stanzas into ejabberd
|
||||
|
||||
Requires: ejabberd 19.08 or higher
|
||||
Author: Nolan Eakins <sneakin@semanticgap.com>
|
||||
Copyright (C) 2008 Nolan Eakins
|
||||
|
||||
|
@ -40,8 +41,6 @@ With that configuration, you can send HTTP POST requests to the URL:
|
|||
Configurable options:
|
||||
|
||||
allowed_ips: IP addresses that can use the rest service.
|
||||
Allowed values: 'all' or a list of Erlang strings.
|
||||
Default value: all
|
||||
Notice that the IP address is checked after the connection is established.
|
||||
If you want to restrict the IP address that listens connections, and
|
||||
only allow a certain IP to be able to connect to the port, then the
|
||||
|
@ -49,18 +48,13 @@ Configurable options:
|
|||
listening IP address in the ejabberd listeners (see the ejabberd Guide).
|
||||
|
||||
allowed_destinations: Allowed destination Jabber ID addresses in the stanza.
|
||||
Allowed values: 'all' or a list of strings.
|
||||
Default value: all
|
||||
|
||||
allowed_stanza_types: Allowed stanza types of the posted stanza.
|
||||
Allowed values: 'all' or a list of strings.
|
||||
Default value: all
|
||||
|
||||
access_commands: Access restrictions to execute ejabberd commands.
|
||||
This option is similar to the option ejabberdctl_access_commands that
|
||||
is documented in the ejabberd Guide.
|
||||
There is more information about AccessCommands in the ejabberd Guide.
|
||||
Default value: []
|
||||
|
||||
Complex example configuration:
|
||||
|
||||
|
@ -88,7 +82,7 @@ modules:
|
|||
- "presence"
|
||||
- "iq"
|
||||
access_commands:
|
||||
restaccess:
|
||||
- restaccess:
|
||||
- registered_users
|
||||
- connected_users
|
||||
|
||||
|
|
|
@ -70,19 +70,19 @@ maybe_post_request(<<$<,_/binary>> = Data, Host, ClientIp) ->
|
|||
Stanza = {xmlel, _, _, _} = fxml_stream:parse_element(Data),
|
||||
Pkt = xmpp:decode(Stanza),
|
||||
allowed = check_stanza(Pkt, Host),
|
||||
?INFO_MSG("Got valid request with IP ~p:~n~p",
|
||||
?DEBUG("Got valid request with IP ~p:~n~p",
|
||||
[ClientIp,
|
||||
Pkt]),
|
||||
post_request(Pkt)
|
||||
catch
|
||||
error:{badmatch, _} = Error ->
|
||||
?DEBUG("Error when processing REST request: ~nData: ~p~nError: ~p", [Data, Error]),
|
||||
?INFO_MSG("Error when processing REST request: ~nData: ~p~nError: ~p", [Data, Error]),
|
||||
{406, [], "Error: REST request is rejected by service."};
|
||||
error:{Reason, _} = Error ->
|
||||
?DEBUG("Error when processing REST request: ~nData: ~p~nError: ~p", [Data, Error]),
|
||||
?INFO_MSG("Error when processing REST request: ~nData: ~p~nError: ~p", [Data, Error]),
|
||||
{500, [], "Error: " ++ atom_to_list(Reason)};
|
||||
Error ->
|
||||
?DEBUG("Error when processing REST request: ~nData: ~p~nError: ~p", [Data, Error]),
|
||||
?INFO_MSG("Error when processing REST request: ~nData: ~p~nError: ~p", [Data, Error]),
|
||||
{500, [], "Error"}
|
||||
end;
|
||||
maybe_post_request(Data, Host, _ClientIp) ->
|
||||
|
@ -107,39 +107,38 @@ ensure_auth_is_provided(Args) ->
|
|||
["--auth", "", "", "" | Args].
|
||||
|
||||
%% This function throws an error if the module is not started in that VHost.
|
||||
try_get_option(Host, OptionName, DefaultValue) ->
|
||||
try_get_option(Host, OptionName) ->
|
||||
case gen_mod:is_loaded(Host, ?MODULE) of
|
||||
true -> ok;
|
||||
_ -> throw({module_must_be_started_in_vhost, ?MODULE, Host})
|
||||
end,
|
||||
gen_mod:get_module_opt(Host, ?MODULE, OptionName, fun(I) -> I end, DefaultValue).
|
||||
gen_mod:get_module_opt(Host, ?MODULE, OptionName).
|
||||
|
||||
get_option_access(Host) ->
|
||||
try_get_option(Host, access_commands, []).
|
||||
try_get_option(Host, access_commands).
|
||||
|
||||
%% This function crashes if the stanza does not satisfy configured restrictions
|
||||
check_stanza(Pkt, Host) ->
|
||||
To = xmpp:get_to(Pkt),
|
||||
check_member_option(Host, jid:encode(To), allowed_destinations),
|
||||
%%+++ {xmlel, StanzaType, _Attrs, _Kids} = Stanza,
|
||||
%%+++ check_member_option(Host, StanzaType, allowed_stanza_types),
|
||||
check_member_option(Host, To, allowed_destinations),
|
||||
Name = xmpp:get_name(Pkt),
|
||||
check_member_option(Host, Name, allowed_stanza_types),
|
||||
allowed.
|
||||
|
||||
check_member_option(Host, ClientIp, allowed_ips) ->
|
||||
true = case try_get_option(Host, allowed_ips, all) of
|
||||
all -> true;
|
||||
true = case try_get_option(Host, allowed_ips) of
|
||||
[] -> true;
|
||||
AllowedValues -> ip_matches(ClientIp, AllowedValues)
|
||||
end;
|
||||
check_member_option(Host, Element, Option) ->
|
||||
true = case try_get_option(Host, Option, all) of
|
||||
all -> true;
|
||||
true = case try_get_option(Host, Option) of
|
||||
[] -> true;
|
||||
AllowedValues -> lists:member(Element, AllowedValues)
|
||||
end.
|
||||
|
||||
ip_matches(ClientIp, AllowedValues) ->
|
||||
lists:any(fun(El) ->
|
||||
{ok, Net, Mask} = acl:parse_ip_netmask(El),
|
||||
acl:acl_rule_matches({ip,{Net,Mask}}, #{ip => {ClientIp,port}}, host)
|
||||
lists:any(fun({Net, Mask}) ->
|
||||
acl:match_acl(useless_host, {ip,{Net,Mask}}, #{ip => {ClientIp,useless_port}})
|
||||
end,
|
||||
AllowedValues).
|
||||
|
||||
|
@ -178,16 +177,16 @@ splitend([92, 34, 32 | Line], Res) -> {Line, Res};
|
|||
splitend([Char | Line], Res) -> splitend(Line, [Char | Res]).
|
||||
|
||||
mod_opt_type(allowed_ips) ->
|
||||
fun (all) -> all; (A) when is_list(A) -> A end;
|
||||
econf:list(econf:ip_mask());
|
||||
mod_opt_type(allowed_destinations) ->
|
||||
fun (all) -> all; (A) when is_list(A) -> A end;
|
||||
econf:list(econf:jid());
|
||||
mod_opt_type(allowed_stanza_types) ->
|
||||
fun (all) -> all; (A) when is_list(A) -> A end;
|
||||
econf:list(econf:enum([<<"iq">>, <<"message">>, <<"presence">>]));
|
||||
mod_opt_type(access_commands) ->
|
||||
fun (A) when is_list(A) -> A end.
|
||||
|
||||
mod_options(_Host) ->
|
||||
[{allowed_ips, all},
|
||||
{allowed_destinations, all},
|
||||
{allowed_stanza_types, all},
|
||||
[{allowed_ips, []},
|
||||
{allowed_destinations, []},
|
||||
{allowed_stanza_types, []},
|
||||
{access_commands, []}].
|
||||
|
|
|
@ -51,7 +51,7 @@
|
|||
start(Host, Opts) ->
|
||||
case whereis(?PROCNAME) of
|
||||
undefined ->
|
||||
Filename = gen_mod:get_opt(filename, Opts, ?DEFAULT_FILENAME),
|
||||
Filename = gen_mod:get_opt(filename, Opts),
|
||||
case filelib:ensure_dir(Filename) of
|
||||
ok ->
|
||||
register(?PROCNAME,
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
|
||||
mod_shcommands - Execute shell commands
|
||||
|
||||
Requires: ejabberd 19.08 or higher
|
||||
Author: Badlop
|
||||
http://ejabberd.im/mod_shcommands
|
||||
|
||||
|
|
|
@ -11,12 +11,13 @@
|
|||
|
||||
-behaviour(gen_mod).
|
||||
|
||||
-export([web_menu_node/3, web_page_node/5,
|
||||
start/2, stop/1]).
|
||||
-export([start/2, stop/1, depends/2, mod_options/1]).
|
||||
-export([web_menu_node/3, web_page_node/5]).
|
||||
|
||||
-include("xmpp.hrl").
|
||||
-include("ejabberd_http.hrl").
|
||||
-include("ejabberd_web_admin.hrl").
|
||||
-include("translate.hrl").
|
||||
|
||||
%%-------------------
|
||||
%% gen_mod functions
|
||||
|
@ -32,19 +33,25 @@ stop(_Host) ->
|
|||
ejabberd_hooks:delete(webadmin_page_node, ?MODULE, web_page_node, 50),
|
||||
ok.
|
||||
|
||||
depends(_Host, _Opts) ->
|
||||
[].
|
||||
|
||||
mod_options(_Host) ->
|
||||
[].
|
||||
|
||||
%%-------------------
|
||||
%% Web Admin Menu
|
||||
%%-------------------
|
||||
|
||||
web_menu_node(Acc, _Node, Lang) ->
|
||||
Acc ++ [{<<"shcommands">>, ?T(<<"Shell Commands">>)}].
|
||||
Acc ++ [{<<"shcommands">>, translate:translate(Lang, ?T("Shell Commands"))}].
|
||||
|
||||
%%-------------------
|
||||
%% Web Admin Page
|
||||
%%-------------------
|
||||
|
||||
web_page_node(_, Node, [<<"shcommands">>], Query, Lang) ->
|
||||
Res = [?XC(<<"h1">>, <<"Shell Commands">>) | get_content(Node, Query, Lang)],
|
||||
Res = [?XC(<<"h1">>, translate:translate(Lang, ?T("Shell Commands"))) | get_content(Node, Query, Lang)],
|
||||
{stop, Res};
|
||||
web_page_node(Acc, _, _, _, _) -> Acc.
|
||||
|
||||
|
@ -53,14 +60,15 @@ web_page_node(Acc, _, _, _, _) -> Acc.
|
|||
%%-------------------
|
||||
|
||||
get_content(Node, Query, Lang) ->
|
||||
Instruct = ?T("Type a command in a textbox and click Execute."),
|
||||
Instruct = translate:translate(Lang, ?T("Type a command in a textbox and click Execute.")),
|
||||
{{CommandCtl, CommandErl, CommandShell}, Res} = case catch parse_and_execute(Query, Node) of
|
||||
{'EXIT', _} -> {{"", "", ""}, Instruct};
|
||||
Result_tuple -> Result_tuple
|
||||
end,
|
||||
TitleHTML = [
|
||||
?XC(<<"p">>, ?T(<<"Type a command in a textbox and click Execute. Use only commands which immediately return a result.">>)),
|
||||
?XC(<<"p">>, ?T(<<"WARNING: Use this only if you know what you are doing.">>))
|
||||
?XC(<<"p">>, translate:translate(Lang, ?T("Type a command in a textbox and click Execute."))),
|
||||
?XC(<<"p">>, translate:translate(Lang, ?T("Use only commands which immediately return a result."))),
|
||||
?XC(<<"p">>, translate:translate(Lang, ?T("WARNING: Use this only if you know what you are doing.")))
|
||||
],
|
||||
CommandHTML =
|
||||
[?XAE(<<"form">>, [{<<"method">>, <<"post">>}],
|
||||
|
@ -70,21 +78,21 @@ get_content(Node, Query, Lang) ->
|
|||
[?X(<<"td">>),
|
||||
?XCT(<<"td">>, <<"ejabberd_ctl">>),
|
||||
?XE(<<"td">>, [?INPUTS(<<"text">>, <<"commandctl">>, list_to_binary(CommandCtl), <<"70">>),
|
||||
?INPUTT(<<"submit">>, <<"executectl">>, <<"Execute">>)])
|
||||
?INPUTT(<<"submit">>, <<"executectl">>, translate:translate(Lang, ?T("Execute")))])
|
||||
]
|
||||
),
|
||||
?XE(<<"tr">>,
|
||||
[?X(<<"td">>),
|
||||
?XCT(<<"td">>, <<"erlang shell">>),
|
||||
?XE(<<"td">>, [?INPUTS(<<"text">>, <<"commanderl">>, list_to_binary(CommandErl), <<"70">>),
|
||||
?INPUTT(<<"submit">>, <<"executeerl">>, <<"Execute">>)])
|
||||
?INPUTT(<<"submit">>, <<"executeerl">>, translate:translate(Lang, ?T("Execute")))])
|
||||
]
|
||||
),
|
||||
?XE(<<"tr">>,
|
||||
[?X(<<"td">>),
|
||||
?XCT(<<"td">>, <<"system shell">>),
|
||||
?XE(<<"td">>, [?INPUTS(<<"text">>, <<"commandshe">>, list_to_binary(CommandShell), <<"70">>),
|
||||
?INPUTT(<<"submit">>, <<"executeshe">>, <<"Execute">>)])
|
||||
?INPUTT(<<"submit">>, <<"executeshe">>, translate:translate(Lang, ?T("Execute")))])
|
||||
]
|
||||
)
|
||||
]
|
||||
|
@ -93,7 +101,7 @@ get_content(Node, Query, Lang) ->
|
|||
ResHTML =
|
||||
[?XAC(<<"textarea">>, [{<<"wrap">>, <<"off">>}, {<<"style">>, <<"font-family:monospace;">>},
|
||||
{<<"name">>, <<"result">>}, {<<"rows">>, <<"30">>}, {<<"cols">>, <<"80">>}],
|
||||
list_to_binary(Res))
|
||||
Res)
|
||||
],
|
||||
TitleHTML ++ CommandHTML ++ ResHTML.
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
|
||||
mod_statsdx - Calculates and gathers statistics actively
|
||||
|
||||
Requires: ejabberd 19.08 or higher
|
||||
Homepage: http://www.ejabberd.im/mod_statsdx
|
||||
Author: Badlop
|
||||
|
||||
|
|
|
@ -11,7 +11,9 @@
|
|||
|
||||
-behaviour(gen_mod).
|
||||
|
||||
-export([start/2, loop/5, stop/1]).
|
||||
|
||||
-export([start/2, stop/1, depends/2, mod_opt_type/1, mod_options/1]).
|
||||
-export([loop/5]).
|
||||
|
||||
-include("xmpp.hrl").
|
||||
-include("mod_roster.hrl").
|
||||
|
@ -26,19 +28,17 @@
|
|||
start(_Host, Opts) ->
|
||||
case whereis(?PROCNAME) of
|
||||
undefined ->
|
||||
Interval = gen_mod:get_opt(interval, Opts, fun(O) -> O end, 5),
|
||||
Interval = gen_mod:get_opt(interval, Opts),
|
||||
I = Interval*60*1000,
|
||||
%I = 9000, %+++
|
||||
|
||||
Type = gen_mod:get_opt(type, Opts, fun(O) -> O end, html),
|
||||
Type = gen_mod:get_opt(type, Opts),
|
||||
|
||||
Split = gen_mod:get_opt(split, Opts, fun(O) -> O end, false),
|
||||
Split = gen_mod:get_opt(split, Opts),
|
||||
|
||||
BaseFilename = binary_to_list(gen_mod:get_opt(basefilename, Opts, fun(O) -> O end, "/tmp/ejasta")),
|
||||
BaseFilename = gen_mod:get_opt(basefilename, Opts),
|
||||
|
||||
Hosts_all = ejabberd_config:get_global_option(hosts, fun(O) -> O end),
|
||||
Hosts1 = gen_mod:get_opt(hosts, Opts, fun(O) -> O end, Hosts_all),
|
||||
Hosts = [binary_to_list(H) || H <- Hosts1],
|
||||
Hosts = gen_mod:get_opt(hosts, Opts),
|
||||
|
||||
register(?PROCNAME, spawn(?MODULE, loop, [I, Hosts, BaseFilename, Type, Split]));
|
||||
_ ->
|
||||
|
@ -61,6 +61,26 @@ stop(_Host) ->
|
|||
?PROCNAME ! stop
|
||||
end.
|
||||
|
||||
depends(_Host, _Opts) ->
|
||||
[{mod_statsdx, hard}].
|
||||
|
||||
mod_opt_type(interval) ->
|
||||
econf:pos_int();
|
||||
mod_opt_type(type) ->
|
||||
econf:enum([html, txt, dat]);
|
||||
mod_opt_type(split) ->
|
||||
econf:bool();
|
||||
mod_opt_type(basefilename) ->
|
||||
econf:string();
|
||||
mod_opt_type(hosts) ->
|
||||
econf:list(econf:domain()).
|
||||
|
||||
mod_options(_Host) ->
|
||||
[{interval, 5},
|
||||
{type, html},
|
||||
{split, false},
|
||||
{basefilename, "/tmp/ejasta"},
|
||||
{hosts, ejabberd_config:get_option(hosts)}].
|
||||
|
||||
%% -------------------
|
||||
%% write_stat*
|
||||
|
@ -96,13 +116,18 @@ write_statsfiles(true, I, Hs, O, T) ->
|
|||
Hs).
|
||||
|
||||
write_statsfile(I, Class, Name, O, T) ->
|
||||
Fn = filename:flatten([O, "-", Class, "-", Name, ".", T]),
|
||||
Fn = filename:flatten([O, "-", Class, "-", to_string(Name), ".", T]),
|
||||
{ok, F} = file:open(Fn, [write]),
|
||||
fwini(F, T),
|
||||
write_stats(I, Class, Name, F, T),
|
||||
fwend(F, T),
|
||||
file:close(F).
|
||||
|
||||
to_string(B) when is_binary(B) ->
|
||||
binary_to_list(B);
|
||||
to_string(S) ->
|
||||
S.
|
||||
|
||||
write_stats(I, server, _Name, F, T) ->
|
||||
fwh(F, "Server statistics", 1, T),
|
||||
fwbl1(F, T),
|
||||
|
|
|
@ -13,7 +13,8 @@
|
|||
|
||||
-behaviour(gen_mod).
|
||||
|
||||
-export([start/2, loop/1, stop/1, mod_opt_type/1, get_statistic/2,
|
||||
-export([start/2, stop/1, depends/2, mod_opt_type/1, mod_options/1]).
|
||||
-export([loop/1, get_statistic/2,
|
||||
received_response/3,
|
||||
%% Commands
|
||||
getstatsdx/1, getstatsdx/2,
|
||||
|
@ -34,22 +35,21 @@
|
|||
-include("mod_roster.hrl").
|
||||
-include("ejabberd_http.hrl").
|
||||
-include("ejabberd_web_admin.hrl").
|
||||
-include("translate.hrl").
|
||||
|
||||
-define(XCTB(Name, Text), ?XCT(list_to_binary(Name), list_to_binary(Text))).
|
||||
|
||||
-define(PROCNAME, ejabberd_mod_statsdx).
|
||||
|
||||
%% Copied from ejabberd_s2s.erl Used in function get_s2sconnections/1
|
||||
-record(s2s, {fromto, pid, key}).
|
||||
-record(s2s, {fromto :: {binary(), binary()},
|
||||
pid :: pid()}).
|
||||
|
||||
%%%==================================
|
||||
%%%% Module control
|
||||
|
||||
start(Host, Opts) ->
|
||||
Hooks = gen_mod:get_opt(hooks, Opts,
|
||||
fun(O) when is_boolean(O) -> O;
|
||||
(traffic) -> traffic
|
||||
end, false),
|
||||
Hooks = gen_mod:get_opt(hooks, Opts),
|
||||
%% Default value for the counters
|
||||
CD = case Hooks of
|
||||
true -> 0;
|
||||
|
@ -79,8 +79,17 @@ stop(Host) ->
|
|||
_ -> ?PROCNAME ! {stop, Host}
|
||||
end.
|
||||
|
||||
mod_opt_type(hooks) -> fun (B) when is_boolean(B) or (B==traffic) -> B end;
|
||||
mod_opt_type(_) -> [hooks].
|
||||
depends(_Host, _Opts) ->
|
||||
[].
|
||||
|
||||
mod_opt_type(hooks) ->
|
||||
econf:enum([false, true, traffic]);
|
||||
mod_opt_type(sessionlog) ->
|
||||
econf:string().
|
||||
|
||||
mod_options(_Host) ->
|
||||
[{hooks, false},
|
||||
{sessionlog, "/tmp/ejabberd_logsession_@HOST@.log"}].
|
||||
|
||||
%%%==================================
|
||||
%%%% Stats Server
|
||||
|
@ -764,7 +773,7 @@ user_logout(User, Host, Resource, _Status) ->
|
|||
ets:update_counter(TableServer, {user_logout, server}, 1),
|
||||
ets:update_counter(TableHost, {user_logout, Host}, 1),
|
||||
|
||||
JID = jlib:make_jid(User, Host, Resource),
|
||||
JID = jid:make(User, Host, Resource),
|
||||
case ets:lookup(TableHost, {session, JID}) of
|
||||
[{_, Client_id, OS_id, Lang, ConnType, _Client, _Version, _OS}] ->
|
||||
ets:delete(TableHost, {session, JID}),
|
||||
|
@ -791,7 +800,7 @@ request_iqversion(User, Host, Resource) ->
|
|||
IQ = #iq{type = get,
|
||||
from = From,
|
||||
to = To,
|
||||
id = randoms:get_string(),
|
||||
id = p1_rand:get_string(),
|
||||
sub_els = [Query]},
|
||||
HandleResponse = fun(#iq{type = result} = IQr) ->
|
||||
spawn(?MODULE, received_response,
|
||||
|
@ -848,7 +857,7 @@ received_response(From, #iq{type = Type, lang = Lang1, sub_els = Elc}) ->
|
|||
update_counter_create(TableHost, {client_conntype, Host, Client_id, ConnType}, 1),
|
||||
update_counter_create(TableServer, {client_conntype, server, Client_id, ConnType}, 1),
|
||||
|
||||
JID = jlib:make_jid(User, Host, Resource),
|
||||
JID = jid:make(User, Host, Resource),
|
||||
ets:insert(TableHost, {{session, JID}, Client_id, OS_id, Lang, ConnType, Client, Version, OS}).
|
||||
|
||||
get_connection_type(User, Host, Resource) ->
|
||||
|
@ -1004,19 +1013,19 @@ localtime_to_string({{Y, Mo, D},{H, Mi, S}}) ->
|
|||
%%%% Web Admin Menu
|
||||
|
||||
web_menu_main(Acc, Lang) ->
|
||||
Acc ++ [{<<"statsdx">>, <<(?T(<<"Statistics">>))/binary, " Dx">>}].
|
||||
Acc ++ [{<<"statsdx">>, <<(translate:translate(Lang, ?T("Statistics")))/binary, " Dx">>}].
|
||||
|
||||
web_menu_node(Acc, _Node, Lang) ->
|
||||
Acc ++ [{<<"statsdx">>, <<(?T(<<"Statistics">>))/binary, " Dx">>}].
|
||||
Acc ++ [{<<"statsdx">>, <<(translate:translate(Lang, ?T("Statistics")))/binary, " Dx">>}].
|
||||
|
||||
web_menu_host(Acc, _Host, Lang) ->
|
||||
Acc ++ [{<<"statsdx">>, <<(?T(<<"Statistics">>))/binary, " Dx">>}].
|
||||
Acc ++ [{<<"statsdx">>, <<(translate:translate(Lang, ?T("Statistics")))/binary, " Dx">>}].
|
||||
|
||||
%%%==================================
|
||||
%%%% Web Admin Page
|
||||
|
||||
web_page_main(_, #request{path=[<<"statsdx">>], lang = Lang} = _Request) ->
|
||||
Res = [?XC(<<"h1">>, <<(?T(<<"Statistics">>))/binary, " Dx">>),
|
||||
Res = [?XC(<<"h1">>, <<(translate:translate(Lang, ?T("Statistics")))/binary, " Dx">>),
|
||||
?XC(<<"h3">>, <<"Accounts">>),
|
||||
?XAE(<<"table">>, [],
|
||||
[?XE(<<"tbody">>, [
|
||||
|
@ -1124,7 +1133,7 @@ web_page_main(_, #request{path=[<<"statsdx">>], lang = Lang} = _Request) ->
|
|||
],
|
||||
{stop, Res};
|
||||
web_page_main(_, #request{path=[<<"statsdx">>, <<"top">>, Topic, Topnumber], q = _Q, lang = Lang} = _Request) ->
|
||||
Res = [?XC(<<"h1">>, <<(?T(<<"Statistics">>))/binary, " Dx">>),
|
||||
Res = [?XC(<<"h1">>, <<(translate:translate(Lang, ?T("Statistics")))/binary, " Dx">>),
|
||||
case Topic of
|
||||
<<"offlinemsg">> -> ?XCT(<<"h2">>, <<"Top offline message queues">>);
|
||||
<<"vcard">> -> ?XCT(<<"h2">>, <<"Top vCard sizes">>);
|
||||
|
@ -1144,7 +1153,7 @@ web_page_main(_, #request{path=[<<"statsdx">> | FilterURL], q = Q, lang = Lang}
|
|||
Filter = parse_url_filter(FilterURL),
|
||||
Sort_query = get_sort_query(Q),
|
||||
FilterS = io_lib:format("~p", [Filter]),
|
||||
Res = [?XC(<<"h1">>, <<(?T(<<"Statistics">>))/binary, " Dx">>),
|
||||
Res = [?XC(<<"h1">>, <<(translate:translate(Lang, ?T("Statistics")))/binary, " Dx">>),
|
||||
?XC(<<"h2">>, list_to_binary("Sessions with: " ++ FilterS)),
|
||||
?XE(<<"table">>,
|
||||
[
|
||||
|
@ -1156,7 +1165,7 @@ web_page_main(_, #request{path=[<<"statsdx">> | FilterURL], q = Q, lang = Lang}
|
|||
web_page_main(Acc, _) -> Acc.
|
||||
|
||||
do_top_table(_Node, Lang, Topic, TopnumberBin, Host) ->
|
||||
List = get_top_users(Host, jlib:binary_to_integer(TopnumberBin), Topic),
|
||||
List = get_top_users(Host, binary_to_integer(TopnumberBin), Topic),
|
||||
%% get_top_users(Topnumber, "roster")
|
||||
{List2, _} = lists:mapfoldl(
|
||||
fun({Value, UserB, ServerB}, Counter) ->
|
||||
|
@ -1238,7 +1247,7 @@ web_page_node(_, Node, [<<"statsdx">>], _Query, Lang) ->
|
|||
rpc:call(Node, mnesia, system_info, [transaction_log_writes]),
|
||||
|
||||
Res =
|
||||
[?XC(<<"h1">>, list_to_binary(io_lib:format(?T("~p statistics"), [Node]))),
|
||||
[?XC(<<"h1">>, list_to_binary(io_lib:format(translate:translate(Lang, ?T("~p statistics")), [Node]))),
|
||||
?XC(<<"h3">>, <<"Connections">>),
|
||||
?XAE(<<"table">>, [],
|
||||
[?XE(<<"tbody">>, [
|
||||
|
@ -1335,7 +1344,7 @@ web_page_node(Acc, _, _, _, _) -> Acc.
|
|||
web_page_host(_, Host,
|
||||
#request{path = [<<"statsdx">>],
|
||||
lang = Lang} = _Request) ->
|
||||
Res = [?XC(<<"h1">>, <<(?T(<<"Statistics">>))/binary, " Dx">>),
|
||||
Res = [?XC(<<"h1">>, <<(translate:translate(Lang, ?T("Statistics")))/binary, " Dx">>),
|
||||
?XC(<<"h2">>, Host),
|
||||
?XC(<<"h3">>, <<"Accounts">>),
|
||||
?XAE(<<"table">>, [],
|
||||
|
@ -1466,7 +1475,7 @@ web_page_host(_, Host,
|
|||
],
|
||||
{stop, Res};
|
||||
web_page_host(_, Host, #request{path=[<<"statsdx">>, <<"top">>, Topic, Topnumber], q = _Q, lang = Lang} = _Request) ->
|
||||
Res = [?XC(<<"h1">>, <<(?T(<<"Statistics">>))/binary, " Dx">>),
|
||||
Res = [?XC(<<"h1">>, <<(translate:translate(Lang, ?T("Statistics")))/binary, " Dx">>),
|
||||
case Topic of
|
||||
<<"offlinemsg">> -> ?XCT(<<"h2">>, <<"Top offline message queues">>);
|
||||
<<"vcard">> -> ?XCT(<<"h2">>, <<"Top vCard sizes">>);
|
||||
|
@ -1486,7 +1495,7 @@ web_page_host(_, Host, #request{path=[<<"statsdx">> | FilterURL], q = Q,
|
|||
lang = Lang} = _Request) ->
|
||||
Filter = parse_url_filter(FilterURL),
|
||||
Sort_query = get_sort_query(Q),
|
||||
Res = [?XC(<<"h1">>, <<(?T(<<"Statistics">>))/binary, " Dx">>),
|
||||
Res = [?XC(<<"h1">>, <<(translate:translate(Lang, ?T("Statistics")))/binary, " Dx">>),
|
||||
?XC(<<"h2">>, list_to_binary("Sessions with: "++io_lib:format("~p", [Filter]))),
|
||||
?XAE(<<"table">>, [],
|
||||
[?XE(<<"tbody">>,
|
||||
|
@ -1550,7 +1559,7 @@ do_sessions_table(_Node, _Lang, Filter, {Sort_direction, Sort_column}, Host) ->
|
|||
Server = binary_to_list(JID#jid.lserver),
|
||||
UserURL = "/admin/server/" ++ Server ++ "/user/" ++ User ++ "/",
|
||||
?XE(<<"tr">>, [
|
||||
?XE(<<"td">>, [?AC(list_to_binary(UserURL), jlib:jid_to_string(JID))]),
|
||||
?XE(<<"td">>, [?AC(list_to_binary(UserURL), jid:encode(JID))]),
|
||||
?XCTB("td", atom_to_list(Client_id)),
|
||||
?XCTB("td", atom_to_list(OS_id)),
|
||||
?XCTB("td", LangS),
|
||||
|
@ -1584,12 +1593,12 @@ get_sessions_filtered(Filter, server) ->
|
|||
ejabberd_config:get_myhosts());
|
||||
get_sessions_filtered(Filter, Host) ->
|
||||
Match = case Filter of
|
||||
[{<<"client">>, Client}] -> {{session, '$1'}, jlib:binary_to_atom(Client), '$2', '$3', '$4', '$5', '$6', '$7'};
|
||||
[{<<"os">>, OS}] -> {{session, '$1'}, '$2', jlib:binary_to_atom(OS), '$3', '$4', '$5', '$6', '$7'};
|
||||
[{<<"conntype">>, ConnType}] -> {{session, '$1'}, '$2', '$3', '$4', jlib:binary_to_atom(ConnType), '$5', '$6', '$7'};
|
||||
[{<<"client">>, Client}] -> {{session, '$1'}, misc:binary_to_atom(Client), '$2', '$3', '$4', '$5', '$6', '$7'};
|
||||
[{<<"os">>, OS}] -> {{session, '$1'}, '$2', misc:binary_to_atom(OS), '$3', '$4', '$5', '$6', '$7'};
|
||||
[{<<"conntype">>, ConnType}] -> {{session, '$1'}, '$2', '$3', '$4', misc:binary_to_atom(ConnType), '$5', '$6', '$7'};
|
||||
[{<<"languages">>, Lang}] -> {{session, '$1'}, '$2', '$3', binary_to_list(Lang), '$4', '$5', '$6', '$7'};
|
||||
[{<<"client">>, Client}, {<<"os">>, OS}] -> {{session, '$1'}, jlib:binary_to_atom(Client), jlib:binary_to_atom(OS), '$3', '$4', '$5', '$6', '$7'};
|
||||
[{<<"client">>, Client}, {<<"conntype">>, ConnType}] -> {{session, '$1'}, jlib:binary_to_atom(Client), '$2', '$3', jlib:binary_to_atom(ConnType), '$5', '$6', '$7'};
|
||||
[{<<"client">>, Client}, {<<"os">>, OS}] -> {{session, '$1'}, misc:binary_to_atom(Client), misc:binary_to_atom(OS), '$3', '$4', '$5', '$6', '$7'};
|
||||
[{<<"client">>, Client}, {<<"conntype">>, ConnType}] -> {{session, '$1'}, misc:binary_to_atom(Client), '$2', '$3', misc:binary_to_atom(ConnType), '$5', '$6', '$7'};
|
||||
_ -> {{session, '$1'}, '$2', '$3', '$4', '$5'}
|
||||
end,
|
||||
ets:match_object(table_name(Host), Match).
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
mod_webpresence - Presence on the Web
|
||||
|
||||
Requires: ejabberd 19.08 or higher
|
||||
Authors: Igor Goryachev, Badlop, runcom
|
||||
http://www.ejabberd.im/mod_webpresence
|
||||
|
||||
|
@ -69,20 +70,12 @@ pixmaps_path:
|
|||
Remember to put the correct path to the pixmaps directory,
|
||||
and make sure the user than runs ejabberd has read access to that directory.
|
||||
Default value: "./pixmaps"
|
||||
port:
|
||||
This informational option is used only when sending a message to the user.
|
||||
If you set a different port in the 'listen' section, set this option too.
|
||||
Default value: 5280
|
||||
path:
|
||||
This informational option is used only when sending a message to the user.
|
||||
If you set a different path in the 'listen' section, set this option too.
|
||||
Default value: "presence"
|
||||
baseurl:
|
||||
This informational option is used only when sending a message to the user
|
||||
and when building the JavaScript code.
|
||||
It is the base part of the URL of the webpresence HTTP content.
|
||||
You can use the keyword @HOST@.
|
||||
If the option is not specified, it takes as default value: http://host:port/path/
|
||||
If the option is not specified, it takes as default value: http://host:52080/presence/
|
||||
|
||||
|
||||
AUTOMATIC ENABLE
|
||||
|
@ -144,8 +137,6 @@ modules:
|
|||
host: "webstatus.@HOST@"
|
||||
access: local
|
||||
pixmaps_path: "/path/to/pixmaps"
|
||||
port: 80
|
||||
path: "status"
|
||||
baseurl: "http://www.example.org/status/"
|
||||
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
|
||||
-include("xmpp.hrl").
|
||||
-include("logger.hrl").
|
||||
-include("translate.hrl").
|
||||
-include("ejabberd_web_admin.hrl").
|
||||
-include("ejabberd_http.hrl").
|
||||
|
||||
|
@ -53,11 +54,7 @@ start_link() ->
|
|||
gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
|
||||
|
||||
start(Host, Opts) ->
|
||||
Default_dir = case code:priv_dir(ejabberd) of
|
||||
{error, _} -> ?PIXMAPS_DIR;
|
||||
Path -> filename:join([Path, ?PIXMAPS_DIR])
|
||||
end,
|
||||
Dir = gen_mod:get_opt(pixmaps_path, Opts, fun(D) -> D end, Default_dir),
|
||||
Dir = gen_mod:get_opt(pixmaps_path, Opts),
|
||||
catch ets:new(pixmaps_dirs, [named_table, public]),
|
||||
ets:insert(pixmaps_dirs, {directory, Dir}),
|
||||
case gen_mod:start_child(?MODULE, Host, Opts) of
|
||||
|
@ -75,19 +72,23 @@ stop(Host) ->
|
|||
gen_mod:stop_child(?MODULE, Host),
|
||||
ok.
|
||||
|
||||
-spec mod_opt_type(atom()) -> fun((term()) -> term()).
|
||||
mod_opt_type(host) -> fun iolist_to_binary/1;
|
||||
mod_opt_type(access) -> fun acl:access_rules_validator/1;
|
||||
mod_opt_type(pixmaps_path) -> fun iolist_to_binary/1;
|
||||
mod_opt_type(host) ->
|
||||
econf:host();
|
||||
mod_opt_type(access) ->
|
||||
econf:acl();
|
||||
mod_opt_type(pixmaps_path) ->
|
||||
econf:directory();
|
||||
mod_opt_type(port) ->
|
||||
fun(I) when is_integer(I), I>0, I<65536 -> I end;
|
||||
mod_opt_type(path) -> fun iolist_to_binary/1;
|
||||
mod_opt_type(baseurl) -> fun iolist_to_binary/1.
|
||||
econf:pos_int();
|
||||
mod_opt_type(path) ->
|
||||
econf:binary();
|
||||
mod_opt_type(baseurl) ->
|
||||
econf:binary().
|
||||
|
||||
-spec mod_options(binary()) -> [{atom(), any()}].
|
||||
mod_options(Host) ->
|
||||
[{host, <<"webpresence.@HOST@">>},
|
||||
{access, none},
|
||||
[{host, <<"webpresence.", Host/binary>>},
|
||||
{access, local},
|
||||
{pixmaps_path, ?PIXMAPS_DIR},
|
||||
{port, 5280},
|
||||
{path, <<"presence">>},
|
||||
|
@ -114,12 +115,9 @@ init([Host, Opts]) ->
|
|||
{attributes, record_info(fields, webpresence)}]),
|
||||
mnesia:add_table_index(webpresence, ridurl),
|
||||
update_table(),
|
||||
MyHost = gen_mod:get_opt_host(Host, Opts, <<"webpresence.@HOST@">>),
|
||||
Access = gen_mod:get_opt(access, Opts, fun(O) -> O end, local),
|
||||
Port = gen_mod:get_opt(port, Opts, fun(O) -> O end, 5280),
|
||||
Path = gen_mod:get_opt(path, Opts, fun(O) -> O end, <<"presence">>),
|
||||
BaseURL1 = gen_mod:get_opt(baseurl, Opts, fun(O) -> O end,
|
||||
iolist_to_binary(io_lib:format(<<"http://~s:~p/~s/">>, [Host, Port, Path]))),
|
||||
MyHost = gen_mod:get_opt(host, Opts),
|
||||
Access = gen_mod:get_opt(access, Opts),
|
||||
BaseURL1 = gen_mod:get_opt(baseurl, Opts),
|
||||
BaseURL2 = ejabberd_regexp:greplace(BaseURL1, <<"@HOST@">>, Host),
|
||||
register_iq_handlers(MyHost),
|
||||
ejabberd_router:register_route(MyHost, Host),
|
||||
|
@ -304,7 +302,7 @@ process_disco_items(#iq{lang = Lang} = IQ) ->
|
|||
name = <<"field">>,
|
||||
attrs = [
|
||||
{<<"type">>, Type},
|
||||
{<<"label">>, ?T(Label)},
|
||||
{<<"label">>, translate:translate(Lang, ?T(Label))},
|
||||
{<<"var">>, Var}
|
||||
],
|
||||
children = Vals
|
||||
|
@ -445,7 +443,7 @@ send_message_registered(WP, To, Host, BaseURL, Lang) ->
|
|||
false -> <<"">>;
|
||||
true -> ?BC([
|
||||
<<" text\n"
|
||||
" text/res/<">>, ?T(<<"Resource">>), <<">\n">>
|
||||
" text/res/<">>, translate:translate(Lang, ?T("Resource")), <<">\n">>
|
||||
])
|
||||
end,
|
||||
Oimage = case WP#webpresence.icon of
|
||||
|
@ -455,9 +453,9 @@ send_message_registered(WP, To, Host, BaseURL, Lang) ->
|
|||
<<" image\n"
|
||||
" image/example.php\n"
|
||||
" image/mypresence.png\n"
|
||||
" image/res/<">>, ?T(<<"Resource">>), <<">\n"
|
||||
" image/theme/<">>, ?T(<<"Icon Theme">>), <<">\n"
|
||||
" image/theme/<">>, ?T(<<"Icon Theme">>), <<">/res/<">>, ?T(<<"Resource">>), <<">\n">>
|
||||
" image/res/<">>, translate:translate(Lang, ?T("Resource")), <<">\n"
|
||||
" image/theme/<">>, translate:translate(Lang, ?T("Icon Theme")), <<">\n"
|
||||
" image/theme/<">>, translate:translate(Lang, ?T("Icon Theme")), <<">/res/<">>, translate:translate(Lang, ?T("Resource")), <<">\n">>
|
||||
])
|
||||
end,
|
||||
Oxml = case WP#webpresence.xml of
|
||||
|
@ -484,24 +482,24 @@ send_message_registered(WP, To, Host, BaseURL, Lang) ->
|
|||
RIDT = ?BC([<<"rid/">>, RID]),
|
||||
{?BC([<<" ">>, RIDT, <<"\n">>]),
|
||||
?BC([<<" ">>, BaseURL, RIDT, <<"/">>, Allowed_type, <<"/\n">>]),
|
||||
?BC([?T(<<"If you forget your RandomID, register again to receive this message.">>), <<"\n">>,
|
||||
?T(<<"To get a new RandomID, disable the option and register again.">>), <<"\n">>])
|
||||
?BC([translate:translate(Lang, ?T("If you forget your RandomID, register again to receive this message.")), <<"\n">>,
|
||||
translate:translate(Lang, ?T("To get a new RandomID, disable the option and register again.")), <<"\n">>])
|
||||
}
|
||||
end,
|
||||
Subject = ?BC([?T(<<"Web Presence">>), <<": ">>, ?T(<<"registered">>)]),
|
||||
Body = ?BC([?T(<<"You have registered:">>), <<" ">>, JIDS, <<"\n\n">>,
|
||||
?T(<<"Use URLs like:">>), <<"\n">>,
|
||||
Subject = ?BC([translate:translate(Lang, ?T("Web Presence")), <<": ">>, translate:translate(Lang, ?T("registered"))]),
|
||||
Body = ?BC([translate:translate(Lang, ?T("You have registered:")), <<" ">>, JIDS, <<"\n\n">>,
|
||||
translate:translate(Lang, ?T("Use URLs like:")), <<"\n">>,
|
||||
<<" ">>, BaseURL, <<"USERID/OUTPUT/\n">>,
|
||||
<<"\n">>,
|
||||
<<"USERID:\n">>, USERID_jid, USERID_rid, <<"\n">>,
|
||||
<<"OUTPUT:\n">>, Oimage, Oxml, Ojs, Otext, Oavatar, <<"\n">>,
|
||||
?T(<<"Example:">>), <<"\n">>, Example_jid, Example_rid, <<"\n">>,
|
||||
translate:translate(Lang, ?T("Example:")), <<"\n">>, Example_jid, Example_rid, <<"\n">>,
|
||||
Text_rid]),
|
||||
send_headline(Host, To, Subject, Body).
|
||||
|
||||
send_message_unregistered(To, Host, Lang) ->
|
||||
Subject = ?BC([?T(<<"Web Presence">>), <<": ">>, ?T(<<"unregistered">>)]),
|
||||
Body = ?BC([?T(<<"You have unregistered.">>), <<"\n\n">>]),
|
||||
Subject = ?BC([translate:translate(Lang, ?T("Web Presence")), <<": ">>, translate:translate(Lang, ?T("unregistered"))]),
|
||||
Body = ?BC([translate:translate(Lang, ?T("You have unregistered.")), <<"\n\n">>]),
|
||||
send_headline(Host, To, Subject, Body).
|
||||
|
||||
send_headline(Host, To, Subject, Body) ->
|
||||
|
@ -704,12 +702,12 @@ make_js(WP, Prs, Show_us, Lang, Q) ->
|
|||
end,
|
||||
?BC([US_string, <<"var jabber_resources=[\n">>, R_string, <<"];">>, CB_string]).
|
||||
|
||||
long_show(<<"available">>, Lang) -> ?T(<<"available">>);
|
||||
long_show(<<"chat">>, Lang) -> ?T(<<"free for chat">>);
|
||||
long_show(<<"away">>, Lang) -> ?T(<<"away">>);
|
||||
long_show(<<"xa">>, Lang) -> ?T(<<"extended away">>);
|
||||
long_show(<<"dnd">>, Lang) -> ?T(<<"do not disturb">>);
|
||||
long_show(_, Lang) -> ?T(<<"unavailable">>).
|
||||
long_show(<<"available">>, Lang) -> translate:translate(Lang, ?T("available"));
|
||||
long_show(<<"chat">>, Lang) -> translate:translate(Lang, ?T("free for chat"));
|
||||
long_show(<<"away">>, Lang) -> translate:translate(Lang, ?T("away"));
|
||||
long_show(<<"xa">>, Lang) -> translate:translate(Lang, ?T("extended away"));
|
||||
long_show(<<"dnd">>, Lang) -> translate:translate(Lang, ?T("do not disturb"));
|
||||
long_show(_, Lang) -> translate:translate(Lang, ?T("unavailable")).
|
||||
|
||||
intund2string(undefined) -> intund2string(0);
|
||||
intund2string(Int) when is_integer(Int) -> list_to_binary(integer_to_list(Int)).
|
||||
|
@ -887,20 +885,20 @@ process(LocalPath, Request) ->
|
|||
|
||||
process2([], #request{lang = Lang1}) ->
|
||||
Lang = parse_lang(Lang1),
|
||||
Title = [?XC(<<"title">>, ?T(<<"Web Presence">>))],
|
||||
Desc = [?XC(<<"p">>, ?BC([ ?T(<<"To publish your presence using this system you need a Jabber account in this Jabber server.">>), <<" ">>,
|
||||
?T(<<"Login with a Jabber client, open the Service Discovery and register in Web Presence.">>),
|
||||
?T(<<"You will receive a message with further instructions.">>)]))],
|
||||
Link_themes = [?AC(<<"themes">>, ?T(<<"Icon Theme">>))],
|
||||
Body = [?XC(<<"h1">>, ?T(<<"Web Presence">>))] ++ Desc ++ Link_themes,
|
||||
Title = [?XC(<<"title">>, translate:translate(Lang, ?T("Web Presence")))],
|
||||
Desc = [?XC(<<"p">>, ?BC([ translate:translate(Lang, ?T("To publish your presence using this system you need a Jabber account in this Jabber server.")), <<" ">>,
|
||||
translate:translate(Lang, ?T("Login with a Jabber client, open the Service Discovery and register in Web Presence.")),
|
||||
translate:translate(Lang, ?T("You will receive a message with further instructions."))]))],
|
||||
Link_themes = [?AC(<<"themes">>, translate:translate(Lang, ?T("Icon Theme")))],
|
||||
Body = [?XC(<<"h1">>, translate:translate(Lang, ?T("Web Presence")))] ++ Desc ++ Link_themes,
|
||||
make_xhtml(Title, Body);
|
||||
|
||||
process2([<<"themes">>], #request{lang = Lang1}) ->
|
||||
Lang = parse_lang(Lang1),
|
||||
Title = [?XC(<<"title">>, ?BC([?T(<<"Web Presence">>), <<" - ">>, ?T("Icon Theme")]))],
|
||||
Title = [?XC(<<"title">>, ?BC([translate:translate(Lang, ?T("Web Presence")), <<" - ">>, translate:translate(Lang, ?T("Icon Theme"))]))],
|
||||
Themes = available_themes(list),
|
||||
Icon_themes = themes_to_xhtml(Themes),
|
||||
Body = [?XC(<<"h1">>, ?T(<<"Icon Theme">>))] ++ Icon_themes,
|
||||
Body = [?XC(<<"h1">>, translate:translate(Lang, ?T("Icon Theme")))] ++ Icon_themes,
|
||||
make_xhtml(Title, Body);
|
||||
|
||||
process2([<<"image">>, Theme, Show], #request{} = _Request) ->
|
||||
|
@ -958,7 +956,7 @@ serve_web_presence(TypeURL, User, Server, Tail, #request{lang = Lang1, q = Q}) -
|
|||
%%%% ---------------------
|
||||
|
||||
web_menu_host(Acc, _Host, Lang) ->
|
||||
[{<<"webpresence">>, ?T(<<"Web Presence">>)} | Acc].
|
||||
[{<<"webpresence">>, translate:translate(Lang, ?T("Web Presence"))} | Acc].
|
||||
|
||||
web_page_host(_, _Host,
|
||||
#request{path = [<<"webpresence">>],
|
||||
|
|
Loading…
Reference in New Issue