24
1
mirror of https://github.com/processone/ejabberd.git synced 2024-06-10 21:47:01 +02:00

mod_mam: more checks for database failure

This commit is contained in:
Evgeny Khramtsov 2019-01-02 21:11:22 +03:00
parent b318c70401
commit 9af70913b5

View File

@ -64,7 +64,7 @@
-callback store(xmlel(), binary(), {binary(), binary()}, chat | groupchat, -callback store(xmlel(), binary(), {binary(), binary()}, chat | groupchat,
jid(), binary(), recv | send, integer()) -> ok | any(). jid(), binary(), recv | send, integer()) -> ok | any().
-callback write_prefs(binary(), binary(), #archive_prefs{}, binary()) -> ok | any(). -callback write_prefs(binary(), binary(), #archive_prefs{}, binary()) -> ok | any().
-callback get_prefs(binary(), binary()) -> {ok, #archive_prefs{}} | error. -callback get_prefs(binary(), binary()) -> {ok, #archive_prefs{}} | error | {error, db_failure}.
-callback select(binary(), jid(), jid(), mam_query:result(), -callback select(binary(), jid(), jid(), mam_query:result(),
#rsm_set{} | undefined, chat | groupchat) -> #rsm_set{} | undefined, chat | groupchat) ->
{[{binary(), non_neg_integer(), xmlel()}], boolean(), count()} | {[{binary(), non_neg_integer(), xmlel()}], boolean(), count()} |
@ -599,37 +599,48 @@ process_iq(#iq{from = #jid{luser = LUser, lserver = LServer},
xmpp:make_error(IQ, xmpp:err_internal_server_error(Txt, Lang)) xmpp:make_error(IQ, xmpp:err_internal_server_error(Txt, Lang))
end; end;
process_iq(#iq{from = #jid{luser = LUser, lserver = LServer}, process_iq(#iq{from = #jid{luser = LUser, lserver = LServer},
to = #jid{lserver = LServer}, to = #jid{lserver = LServer}, lang = Lang,
type = get, sub_els = [#mam_prefs{xmlns = NS}]} = IQ) -> type = get, sub_els = [#mam_prefs{xmlns = NS}]} = IQ) ->
Prefs = get_prefs(LUser, LServer), case get_prefs(LUser, LServer) of
PrefsEl = prefs_el(Prefs#archive_prefs.default, {ok, Prefs} ->
Prefs#archive_prefs.always, PrefsEl = prefs_el(Prefs#archive_prefs.default,
Prefs#archive_prefs.never, Prefs#archive_prefs.always,
NS), Prefs#archive_prefs.never,
xmpp:make_iq_result(IQ, PrefsEl); NS),
xmpp:make_iq_result(IQ, PrefsEl);
{error, _} ->
Txt = <<"Database failure">>,
xmpp:make_error(IQ, xmpp:err_internal_server_error(Txt, Lang))
end;
process_iq(IQ) -> process_iq(IQ) ->
xmpp:make_error(IQ, xmpp:err_not_allowed()). xmpp:make_error(IQ, xmpp:err_not_allowed()).
process_iq(LServer, #iq{from = #jid{luser = LUser}, lang = Lang, process_iq(LServer, #iq{from = #jid{luser = LUser}, lang = Lang,
sub_els = [SubEl]} = IQ, MsgType) -> sub_els = [SubEl]} = IQ, MsgType) ->
case MsgType of Ret = case MsgType of
chat -> chat ->
maybe_activate_mam(LUser, LServer); maybe_activate_mam(LUser, LServer);
{groupchat, _Role, _MUCState} -> {groupchat, _Role, _MUCState} ->
ok ok
end, end,
case SubEl of case Ret of
#mam_query{rsm = #rsm_set{index = I}} when is_integer(I) -> ok ->
Txt = <<"Unsupported <index/> element">>, case SubEl of
xmpp:make_error(IQ, xmpp:err_feature_not_implemented(Txt, Lang)); #mam_query{rsm = #rsm_set{index = I}} when is_integer(I) ->
#mam_query{rsm = RSM, xmlns = NS} -> Txt = <<"Unsupported <index/> element">>,
case parse_query(SubEl, Lang) of xmpp:make_error(IQ, xmpp:err_feature_not_implemented(Txt, Lang));
{ok, Query} -> #mam_query{rsm = RSM, xmlns = NS} ->
NewRSM = limit_max(RSM, NS), case parse_query(SubEl, Lang) of
select_and_send(LServer, Query, NewRSM, IQ, MsgType); {ok, Query} ->
{error, Err} -> NewRSM = limit_max(RSM, NS),
xmpp:make_error(IQ, Err) select_and_send(LServer, Query, NewRSM, IQ, MsgType);
end {error, Err} ->
xmpp:make_error(IQ, Err)
end
end;
{error, _} ->
Txt = <<"Database failure">>,
xmpp:make_error(IQ, xmpp:err_internal_server_error(Txt, Lang))
end. end.
-spec should_archive(message(), binary()) -> boolean(). -spec should_archive(message(), binary()) -> boolean().
@ -823,23 +834,27 @@ may_enter_room(From, MUCState) ->
-spec store_msg(message(), binary(), binary(), jid(), send | recv) -spec store_msg(message(), binary(), binary(), jid(), send | recv)
-> ok | pass | any(). -> ok | pass | any().
store_msg(Pkt, LUser, LServer, Peer, Dir) -> store_msg(Pkt, LUser, LServer, Peer, Dir) ->
Prefs = get_prefs(LUser, LServer), case get_prefs(LUser, LServer) of
case {should_archive_peer(LUser, LServer, Prefs, Peer), Pkt} of {ok, Prefs} ->
{true, #message{meta = #{sm_copy := true}}} -> case {should_archive_peer(LUser, LServer, Prefs, Peer), Pkt} of
ok; % Already stored. {true, #message{meta = #{sm_copy := true}}} ->
{true, _} -> ok; % Already stored.
case ejabberd_hooks:run_fold(store_mam_message, LServer, Pkt, {true, _} ->
[LUser, LServer, Peer, chat, Dir]) of case ejabberd_hooks:run_fold(store_mam_message, LServer, Pkt,
drop -> [LUser, LServer, Peer, chat, Dir]) of
pass; drop ->
Pkt1 -> pass;
US = {LUser, LServer}, Pkt1 ->
ID = get_stanza_id(Pkt1), US = {LUser, LServer},
El = xmpp:encode(Pkt1), ID = get_stanza_id(Pkt1),
Mod = gen_mod:db_mod(LServer, ?MODULE), El = xmpp:encode(Pkt1),
Mod:store(El, LServer, US, chat, Peer, <<"">>, Dir, ID) Mod = gen_mod:db_mod(LServer, ?MODULE),
Mod:store(El, LServer, US, chat, Peer, <<"">>, Dir, ID)
end;
{false, _} ->
pass
end; end;
{false, _} -> {error, _} ->
pass pass
end. end.
@ -895,18 +910,20 @@ get_prefs(LUser, LServer) ->
end, end,
case Res of case Res of
{ok, Prefs} -> {ok, Prefs} ->
Prefs; {ok, Prefs};
{error, _} ->
{error, db_failure};
error -> error ->
ActivateOpt = gen_mod:get_module_opt( ActivateOpt = gen_mod:get_module_opt(
LServer, ?MODULE, LServer, ?MODULE,
request_activates_archiving), request_activates_archiving),
case ActivateOpt of case ActivateOpt of
true -> true ->
#archive_prefs{us = {LUser, LServer}, default = never}; {ok, #archive_prefs{us = {LUser, LServer}, default = never}};
false -> false ->
Default = gen_mod:get_module_opt( Default = gen_mod:get_module_opt(
LServer, ?MODULE, default), LServer, ?MODULE, default),
#archive_prefs{us = {LUser, LServer}, default = Default} {ok, #archive_prefs{us = {LUser, LServer}, default = Default}}
end end
end. end.
@ -935,6 +952,8 @@ maybe_activate_mam(LUser, LServer) ->
case Res of case Res of
{ok, _Prefs} -> {ok, _Prefs} ->
ok; ok;
{error, _} ->
{error, db_failure};
error -> error ->
Default = gen_mod:get_module_opt( Default = gen_mod:get_module_opt(
LServer, ?MODULE, default), LServer, ?MODULE, default),