Skip to content

Commit

Permalink
Merge pull request #3188 from esl/mod-last-with-dynamic-domains
Browse files Browse the repository at this point in the history
Support dynamic domains in mod_last
  • Loading branch information
vkatsuba authored Jul 28, 2021
2 parents 324c23b + 21c00e5 commit 9a3cd46
Show file tree
Hide file tree
Showing 20 changed files with 304 additions and 261 deletions.
2 changes: 2 additions & 0 deletions big_tests/dynamic_domains.spec
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@

{suites, "tests", inbox_extensions_SUITE}.

{suites, "tests", last_SUITE}.

{suites, "tests", mam_SUITE}.

{suites, "tests", mod_ping_SUITE}.
Expand Down
12 changes: 4 additions & 8 deletions big_tests/test.config
Original file line number Diff line number Diff line change
Expand Up @@ -250,8 +250,7 @@
connection.tls.verify_peer = true
connection.tls.cacertfile = \"priv/ssl/cacert.pem\"
connection.tls.server_name_indication = false"},
{mod_last, "[modules.mod_last]
backend = \"rdbms\""},
{mod_last, " backend = \"rdbms\""},
{mod_privacy, " backend = \"rdbms\""},
{mod_private, "[modules.mod_private]
backend = \"rdbms\""},
Expand All @@ -272,8 +271,7 @@
workers = 5
connection.driver = \"odbc\"
connection.settings = \"DSN=mongoose-mssql;UID=sa;PWD=mongooseim_secret+ESL123\""},
{mod_last, "[modules.mod_last]
backend = \"rdbms\""},
{mod_last, " backend = \"rdbms\""},
{mod_privacy, " backend = \"rdbms\""},
{mod_private, "[modules.mod_private]
backend = \"rdbms\""},
Expand Down Expand Up @@ -304,8 +302,7 @@
connection.tls.verify_peer = true
connection.tls.cacertfile = \"priv/ssl/cacert.pem\"
connection.tls.versions = [\"tlsv1.2\"]"},
{mod_last, "[modules.mod_last]
backend = \"rdbms\""},
{mod_last, " backend = \"rdbms\""},
{mod_privacy, " backend = \"rdbms\""},
{mod_private, "[modules.mod_private]
backend = \"rdbms\""},
Expand Down Expand Up @@ -372,8 +369,7 @@
connection.tls.ciphers = \"AES256-SHA:DHE-RSA-AES128-SHA256\"
connection.tls.server_name_indication = false
connection.tls.cacertfile = \"priv/ssl/cacert.pem\""},
{mod_last, "[modules.mod_last]
backend = \"riak\""},
{mod_last, " backend = \"riak\""},
{mod_privacy, " backend = \"riak\""},
{mod_private, "[modules.mod_private]
backend = \"riak\""},
Expand Down
3 changes: 2 additions & 1 deletion big_tests/tests/ejabberdctl_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -1289,8 +1289,9 @@ get_sha(AccountPass) ->
|| X <- binary_to_list(crypto:hash(sha, AccountPass))]).

set_last(User, Domain, TStamp) ->
HostType = domain_helper:host_type(),
rpc(mim(), mod_last, store_last_info,
[escalus_utils:jid_to_lower(User), Domain, TStamp, <<>>]).
[HostType, escalus_utils:jid_to_lower(User), Domain, TStamp, <<>>]).

delete_users(Config) ->
Users = escalus_users:get_users([alice, bob, kate, mike]),
Expand Down
10 changes: 4 additions & 6 deletions big_tests/tests/mongoose_helper.erl
Original file line number Diff line number Diff line change
Expand Up @@ -127,14 +127,12 @@ do_clear_last_activity(_Config, User) when is_binary(User) ->
do_clear_last_activity(Config, Users) when is_list(Users) ->
lists:foreach(fun(User) -> do_clear_last_activity(Config, User) end, Users).

new_mongoose_acc(Location, Server) ->
successful_rpc(mongoose_acc, new, [#{ location => Location,
lserver => Server,
element => undefined }]).

new_mongoose_acc(Server) ->
new_mongoose_acc(?LOCATION, Server).

new_mongoose_acc(Location, Server) ->
{ok, HostType} = rpc(mim(), mongoose_domain_core, get_host_type, [Server]),
successful_rpc(mongoose_acc, new, [#{ location => ?LOCATION,
successful_rpc(mongoose_acc, new, [#{ location => Location,
lserver => Server,
host_type => HostType,
element => undefined }]).
Expand Down
10 changes: 6 additions & 4 deletions big_tests/tests/rdbms_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -314,10 +314,12 @@ arguments_from_two_tables(Config) ->
<<"SELECT users.username from users "
" LEFT JOIN last ON (last.username = users.username) "
" WHERE users.password = ? AND last.seconds > ?">>),
sql_query(Config, "INSERT INTO users (username, server, password) VALUES ('alice', 'domain', 'secret')"),
sql_query(Config, "INSERT INTO users (username, server, password) VALUES ('bob', 'domain', 'billy')"),
sql_query(Config, "INSERT INTO last (username, seconds, state) VALUES ('alice', 1615368268, 'ok')"),
sql_query(Config, "INSERT INTO last (username, seconds, state) VALUES ('bob', 1610000000, 'cool')"),
UserInsert = "INSERT INTO users (username, server, password) VALUES ",
sql_query(Config, UserInsert ++ "('alice', 'domain', 'secret')"),
sql_query(Config, UserInsert ++ "('bob', 'domain', 'billy')"),
LastInsert = "INSERT INTO last (username, server, seconds, state) VALUES ",
sql_query(Config, LastInsert ++ "('alice', 'domain', 1615368268, 'ok')"),
sql_query(Config, LastInsert ++ "('bob', 'domain', 1610000000, 'cool')"),
SelectResult = sql_execute(Config, select_multi_args, [<<"secret">>, 1611000000]),
?assert_equal({selected, [{<<"alice">>}]}, SelectResult),
erase_users(Config),
Expand Down
6 changes: 6 additions & 0 deletions priv/mssql2012.sql
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,20 @@ GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[last](
[server] [nvarchar](250) NOT NULL,
[username] [nvarchar](250) NOT NULL,
[seconds] [int] NOT NULL,
[state] [nvarchar](max) NOT NULL,
CONSTRAINT [PK_last_username] PRIMARY KEY CLUSTERED
(
[server] ASC,
[username] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO

CREATE INDEX i_last_server_seconds ON last (server, seconds);
GO

GO
SET ANSI_PADDING OFF
Expand Down
11 changes: 5 additions & 6 deletions priv/mysql.sql
Original file line number Diff line number Diff line change
Expand Up @@ -46,17 +46,16 @@ CREATE TABLE users (
) CHARACTER SET utf8mb4
ROW_FORMAT=DYNAMIC;


CREATE TABLE last (
username varchar(250) PRIMARY KEY,
server varchar(250),
username varchar(250),
seconds int NOT NULL,

state text NOT NULl
state text NOT NULL,
PRIMARY KEY (server, username)
) CHARACTER SET utf8mb4
ROW_FORMAT=DYNAMIC;

CREATE INDEX i_last_seconds ON last(seconds);

CREATE INDEX i_last_server_seconds ON last (server, seconds);

CREATE TABLE rosterusers (
server varchar(250) NOT NULL,
Expand Down
8 changes: 5 additions & 3 deletions priv/pg.sql
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,14 @@ CREATE TABLE users (


CREATE TABLE last (
username varchar(250) PRIMARY KEY,
server varchar(250),
username varchar(250),
seconds integer NOT NULL,
state text NOT NULL
state text NOT NULL,
PRIMARY KEY (server, username)
);

CREATE INDEX i_last_seconds ON last USING btree (seconds);
CREATE INDEX i_last_server_seconds ON last USING btree (server, seconds);


CREATE TABLE rosterusers (
Expand Down
2 changes: 1 addition & 1 deletion rel/files/mongooseim.toml
Original file line number Diff line number Diff line change
Expand Up @@ -230,8 +230,8 @@
[modules.mod_muc_light_commands]

{{#mod_last}}
[modules.mod_last]
{{{mod_last}}}

{{/mod_last}}
[modules.mod_stream_management]

Expand Down
4 changes: 4 additions & 0 deletions rel/mim1.vars-toml.config
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@

[host_config.modules.mod_disco]

{{#mod_last}}
[host_config.modules.mod_last]
{{{mod_last}}}
{{/mod_last}}
{{#mod_offline}}
[host_config.modules.mod_offline]
{{{mod_offline}}}
Expand Down
10 changes: 6 additions & 4 deletions rel/vars-toml.config.in
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,15 @@
shaper_rule = \"fast\"
ip_address = \"127.0.0.1\"
password = \"secret\""}.
{mod_cache_users, ""}. % enabled, no options
{mod_last, "[modules.mod_last]"}.
{mod_offline, ""}. % enabled, no options

%% "" means that the module is enabled without any options
{mod_cache_users, ""}.
{mod_last, ""}.
{mod_offline, ""}.
{mod_privacy, ""}.
{mod_blocking, "[modules.mod_blocking]"}.
{mod_private, "[modules.mod_private]"}.
{mod_roster, ""}. % enabled, no options
{mod_roster, ""}.
{mod_vcard, "[modules.mod_vcard]
host = \"vjud.@HOST@\""}.
{sm_backend, "\"mnesia\""}.
Expand Down
15 changes: 8 additions & 7 deletions src/admin_extra/service_admin_extra_accounts.erl
Original file line number Diff line number Diff line change
Expand Up @@ -178,14 +178,14 @@ get_sha(AccountPass) ->


-spec num_active_users(jid:server(), integer()) -> non_neg_integer().
num_active_users(Host, Days) ->
num_active_users(Domain, Days) ->
TimeStamp = erlang:system_time(second),
TS = TimeStamp - Days * 86400,
case catch mod_last:count_active_users(Host, TS) of
{'EXIT', _Reason} ->
0;
Val ->
Val
try
{ok, HostType} = mongoose_domain_api:get_domain_host_type(Domain),
mod_last:count_active_users(HostType, Domain, TS)
catch _:_ ->
0
end.


Expand Down Expand Up @@ -237,7 +237,8 @@ delete_old_user({LUser, LServer}, TimeStampNow, SecOlder) ->
SecOlder :: non_neg_integer()) -> boolean().
delete_old_user_if_nonactive_long_enough(JID, TimeStampNow, SecOlder) ->
{LUser, LServer} = jid:to_lus(JID),
case mod_last:get_last_info(LUser, LServer) of
{ok, HostType} = mongoose_domain_api:get_domain_host_type(LServer),
case mod_last:get_last_info(HostType, LUser, LServer) of
{ok, TimeStamp, _Status} ->
%% get his age
Sec = TimeStampNow - TimeStamp,
Expand Down
4 changes: 2 additions & 2 deletions src/admin_extra/service_admin_extra_last.erl
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,11 @@ set_last(User, Server, Timestamp, Status) ->
JID = jid:make(User, Server, <<>>),
case ejabberd_auth:does_user_exist(JID) of
true ->
mod_last:store_last_info(JID#jid.luser, JID#jid.lserver, Timestamp, Status),
{ok, HostType} = mongoose_domain_api:get_host_type(JID#jid.lserver),
mod_last:store_last_info(HostType, JID#jid.luser, JID#jid.lserver, Timestamp, Status),
{ok, io_lib:format("Last activity for user ~s is set as ~B with status ~s",
[jid:to_binary(JID), Timestamp, Status])};
false ->
String = io_lib:format("User ~s@~s does not exist", [User, Server]),
{user_does_not_exist, String}
end.

28 changes: 12 additions & 16 deletions src/auth/ejabberd_auth_external.erl
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ check_password_extauth(HostType, LUser, LServer, Password) ->
Password :: binary(),
CacheTime :: integer()) -> boolean().
check_password_cache(HostType, LUser, LServer, Password, CacheTime) ->
case get_last_access(LUser, LServer) of
case get_last_access(HostType, LUser, LServer) of
online ->
check_password_internal(HostType, LUser, LServer, Password);
never ->
Expand Down Expand Up @@ -272,7 +272,7 @@ get_password_internal(HostType, LUser, LServer) ->
LServer :: jid:lserver(),
CacheTime :: integer()) -> false | binary().
get_password_cache(HostType, LUser, LServer, CacheTime) ->
case get_last_access(LUser, LServer) of
case get_last_access(HostType, LUser, LServer) of
online ->
get_password_internal(HostType, LUser, LServer);
never ->
Expand Down Expand Up @@ -348,14 +348,13 @@ is_fresh_enough(TimeStampLast, CacheTime) ->

%% @doc Code copied from mod_configure.erl
%% Code copied from web/ejabberd_web_admin.erl
-spec get_last_access(User :: jid:user(),
Server :: jid:server()
) -> online | never | mod_last_required | integer().
get_last_access(User, Server) ->
JID = jid:make(User, Server, <<>>),
-spec get_last_access(mongooseim:host_type(), jid:luser(), jid:lserver()) ->
online | never | mod_last_required | integer().
get_last_access(HostType, LUser, LServer) ->
JID = jid:make_noprep(LUser, LServer, <<>>),
case ejabberd_sm:get_user_resources(JID) of
[] ->
case get_last_info(User, Server) of
case get_last_info(HostType, LUser, LServer) of
mod_last_required ->
mod_last_required;
not_found ->
Expand All @@ -367,14 +366,11 @@ get_last_access(User, Server) ->
online
end.


-spec get_last_info(User :: jid:user(),
Server :: jid:server()
) -> {ok, Timestamp :: integer(), Status :: binary()}
| not_found | mod_last_required.
get_last_info(User, Server) ->
case gen_mod:is_loaded(Server, mod_last) of
true -> mod_last:get_last_info(User, Server);
-spec get_last_info(mongooseim:host_type(), jid:luser(), jid:lserver()) ->
{ok, mod_last:timestamp(), mod_last:status()} | not_found | mod_last_required.
get_last_info(HostType, LUser, LServer) ->
case gen_mod:is_loaded(HostType, mod_last) of
true -> mod_last:get_last_info(HostType, LUser, LServer);
_ -> mod_last_required
end.

Expand Down
Loading

0 comments on commit 9a3cd46

Please sign in to comment.