./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 53 case ejabberd_auth:does_user_exist(JID) of
25 true ->
26 49 {ok, HostType} = mongoose_domain_api:get_host_type(Server),
27 49 ok = mod_last:store_last_info(HostType, User, Server, Timestamp, Status),
28 49 {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 12 case ejabberd_auth:does_user_exist(JID) of
37 true ->
38 8 {ok, HostType} = mongoose_domain_api:get_host_type(Server),
39 8 case mod_last:get_last_info(HostType, User, Server) of
40 {ok, Timestamp, Status} ->
41 5 {ok, #{timestamp => Timestamp, status => Status}};
42 not_found ->
43 3 {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 11 LDomain = jid:nameprep(Domain),
53 11 case mongoose_domain_api:get_host_type(LDomain) of
54 {ok, HostType} ->
55 9 {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 12 OldUsers = lists:append([list_old_users(HostType, Domain, Timestamp) ||
63 12 HostType <- ?ALL_HOST_TYPES,
64 72 Domain <- mongoose_domain_api:get_domains_by_host_type(HostType)]),
65 12 {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 9 LDomain = jid:nameprep(Domain),
71 9 case mongoose_domain_api:get_host_type(LDomain) of
72 {ok, HostType} ->
73 5 {ok, list_old_users(HostType, LDomain, Timestamp)};
74 {error, not_found} ->
75 4 ?DOMAIN_NOT_FOUND_RESULT
76 end.
77
78 -spec remove_old_users(timestamp()) -> {ok, [old_user()]}.
79 remove_old_users(Timestamp) ->
80 4 {ok, OldUsers} = list_old_users(Timestamp),
81 4 ok = remove_users(OldUsers),
82 4 {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 4 case list_old_users(Domain, Timestamp) of
88 {ok, OldUsers} ->
89 2 ok = remove_users(OldUsers),
90 2 {ok, OldUsers};
91 Error ->
92 2 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 41 Users = ejabberd_auth:get_vh_registered_users(Domain),
100 41 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 30 JID = jid:make_bare(LU, LS),
106 30 case ejabberd_sm:get_user_resources(JID) of
107 [] ->
108 28 case mod_last:get_last_info(HostType, LU, LS) of
109 {ok, UserTimestamp, _} when UserTimestamp < Timestamp ->
110 13 {true, {JID, UserTimestamp}};
111 not_found ->
112 6 {true, {JID, null}};
113 _ ->
114 9 false
115 end;
116 _ ->
117 2 false
118 end.
119
120 -spec remove_users([old_user()]) -> ok.
121 remove_users(Users) ->
122 6 lists:foreach(fun({JID, _}) -> ok = ejabberd_auth:remove_user(JID) end, Users).
Line Hits Source