./ct_report/coverage/mod_last_api.COVER.html

1 %% @doc Provide an interface for frontends (like graphql or ctl) to manage last activity.
2 -module(mod_last_api).
3
4 -export([get_last/1, set_last/3, count_active_users/2]).
5
6 -export([list_old_users/1, list_old_users/2,
7 remove_old_users/1, remove_old_users/2]).
8
9 -include("jlib.hrl").
10 -include("mongoose.hrl").
11
12 -type old_user() :: {jid:jid(), null | timestamp()}.
13 -type info() :: #{timestamp := mod_last:timestamp(), status := mod_last:status()}.
14 -type timestamp() :: mod_last:timestamp().
15 -type status() :: mod_last:status().
16 -type host_type() :: mongooseim:host_type().
17
18 -define(USER_NOT_FOUND_RESULT(User, Server),
19 {user_does_not_exist, io_lib:format("User ~s@~s does not exist", [User, Server])}).
20 -define(DOMAIN_NOT_FOUND_RESULT, {domain_not_found, <<"Domain not found">>}).
21
22 -spec set_last(jid:jid(), timestamp(), status()) -> {ok, info()} | {user_does_not_exist, iolist()}.
23 set_last(#jid{luser = User, lserver = Server} = JID, Timestamp, Status) ->
24 18 case ejabberd_auth:does_user_exist(JID) of
25 true ->
26 14 {ok, HostType} = mongoose_domain_api:get_host_type(Server),
27 14 ok = mod_last:store_last_info(HostType, User, Server, Timestamp, Status),
28 14 {ok, #{timestamp => Timestamp, status => Status}};
29 false ->
30 4 ?USER_NOT_FOUND_RESULT(User, Server)
31 end.
32
33 -spec get_last(jid:jid()) ->
34 {ok, info()} | {last_not_found | user_does_not_exist, iodata()}.
35 get_last(#jid{luser = User, lserver = Server} = JID) ->
36 10 case ejabberd_auth:does_user_exist(JID) of
37 true ->
38 6 {ok, HostType} = mongoose_domain_api:get_host_type(Server),
39 6 case mod_last:get_last_info(HostType, User, Server) of
40 {ok, Timestamp, Status} ->
41 4 {ok, #{timestamp => Timestamp, status => Status}};
42 not_found ->
43 2 {last_not_found, <<"Given user's last info not found">>}
44 end;
45 false ->
46 4 ?USER_NOT_FOUND_RESULT(User, Server)
47 end.
48
49 -spec count_active_users(jid:server(), timestamp()) ->
50 {ok, non_neg_integer()} | {domain_not_found, binary()}.
51 count_active_users(Domain, Timestamp) ->
52 8 LDomain = jid:nameprep(Domain),
53 8 case mongoose_domain_api:get_host_type(LDomain) of
54 {ok, HostType} ->
55 6 {ok, mod_last:count_active_users(HostType, LDomain, Timestamp)};
56 {error, not_found} ->
57 2 ?DOMAIN_NOT_FOUND_RESULT
58 end.
59
60 -spec list_old_users(timestamp()) -> {ok, [old_user()]}.
61 list_old_users(Timestamp) ->
62
:-(
OldUsers = lists:append([list_old_users(HostType, Domain, Timestamp) ||
63
:-(
HostType <- ?ALL_HOST_TYPES,
64
:-(
Domain <- mongoose_domain_api:get_domains_by_host_type(HostType)]),
65
:-(
{ok, OldUsers}.
66
67 -spec list_old_users(jid:server(), timestamp()) ->
68 {ok, [old_user()]} | {domain_not_found, binary()}.
69 list_old_users(Domain, Timestamp) ->
70
:-(
LDomain = jid:nameprep(Domain),
71
:-(
case mongoose_domain_api:get_host_type(LDomain) of
72 {ok, HostType} ->
73
:-(
{ok, list_old_users(HostType, LDomain, Timestamp)};
74 {error, not_found} ->
75
:-(
?DOMAIN_NOT_FOUND_RESULT
76 end.
77
78 -spec remove_old_users(timestamp()) -> {ok, [old_user()]}.
79 remove_old_users(Timestamp) ->
80
:-(
{ok, OldUsers} = list_old_users(Timestamp),
81
:-(
ok = remove_users(OldUsers),
82
:-(
{ok, OldUsers}.
83
84 -spec remove_old_users(jid:server(), timestamp()) ->
85 {ok, [old_user()]} | {domain_not_found, binary()}.
86 remove_old_users(Domain, Timestamp) ->
87
:-(
case list_old_users(Domain, Timestamp) of
88 {ok, OldUsers} ->
89
:-(
ok = remove_users(OldUsers),
90
:-(
{ok, OldUsers};
91 Error ->
92
:-(
Error
93 end.
94
95 %% Internal
96
97 -spec list_old_users(host_type(), jid:lserver(), timestamp()) -> [old_user()].
98 list_old_users(HostType, Domain, Timestamp) ->
99
:-(
Users = ejabberd_auth:get_vh_registered_users(Domain),
100
:-(
lists:filtermap(fun(U) -> prepare_old_user(HostType, U, Timestamp) end, Users).
101
102 -spec prepare_old_user(host_type(), jid:simple_bare_jid(), timestamp()) ->
103 false | {true, old_user()}.
104 prepare_old_user(HostType, {LU, LS}, Timestamp) ->
105
:-(
JID = jid:make_bare(LU, LS),
106
:-(
case ejabberd_sm:get_user_resources(JID) of
107 [] ->
108
:-(
case mod_last:get_last_info(HostType, LU, LS) of
109 {ok, UserTimestamp, _} when UserTimestamp < Timestamp ->
110
:-(
{true, {JID, UserTimestamp}};
111 not_found ->
112
:-(
{true, {JID, null}};
113 _ ->
114
:-(
false
115 end;
116 _ ->
117
:-(
false
118 end.
119
120 -spec remove_users([old_user()]) -> ok.
121 remove_users(Users) ->
122
:-(
lists:foreach(fun({JID, _}) -> ok = ejabberd_auth:remove_user(JID) end, Users).
Line Hits Source