From 689ad91f8abcbe059e6cbdc138b43bc53e1fe89b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chrz=C4=85szcz?= Date: Wed, 19 Oct 2022 16:29:57 +0200 Subject: [PATCH] WIP --- big_tests/tests/graphql_stanza_SUITE.erl | 18 ++-- big_tests/tests/rest_SUITE.erl | 8 +- ...mongoose_graphql_stanza_admin_mutation.erl | 22 +++-- src/graphql/mongoose_graphql_helper.erl | 2 +- .../mongoose_graphql_stanza_user_mutation.erl | 51 +++-------- src/mam/mod_mam_utils.erl | 10 --- .../mongoose_admin_api_messages.erl | 12 +-- .../mongoose_admin_api_stanzas.erl | 37 ++------ .../mongoose_client_api_messages.erl | 7 +- src/mongoose_stanza_api.erl | 86 ++++++++++++++++++- src/mongoose_stanza_helper.erl | 64 +++++++------- 11 files changed, 160 insertions(+), 157 deletions(-) diff --git a/big_tests/tests/graphql_stanza_SUITE.erl b/big_tests/tests/graphql_stanza_SUITE.erl index ede9e54a6be..0b3361b14c6 100644 --- a/big_tests/tests/graphql_stanza_SUITE.erl +++ b/big_tests/tests/graphql_stanza_SUITE.erl @@ -185,8 +185,7 @@ admin_send_message_headline_story(Config, Alice, Bob) -> To = escalus_client:short_jid(Bob), Res = send_message_headline(From, To, <<"Welcome">>, <<"Hi!">>, Config), #{<<"id">> := MamID} = get_ok_value([data, stanza, sendMessageHeadLine], Res), - % Headlines are not stored in MAM - <<>> = MamID, + assert_not_empty(MamID, Config), escalus:assert(is_message, escalus:wait_for_stanza(Bob)). user_send_message_headline(Config) -> @@ -198,8 +197,7 @@ user_send_message_headline_story(Config, Alice, Bob) -> To = escalus_client:short_jid(Bob), Res = user_send_message_headline(Alice, From, To, <<"Welcome">>, <<"Hi!">>, Config), #{<<"id">> := MamID} = get_ok_value([data, stanza, sendMessageHeadLine], Res), - % Headlines are not stored in MAM - <<>> = MamID, + assert_not_empty(MamID, Config), escalus:assert(is_message, escalus:wait_for_stanza(Bob)). user_send_message_headline_with_spoofed_from(Config) -> @@ -312,8 +310,8 @@ admin_send_stanza_from_unknown_user_story(Config, Bob) -> From = <<"YeeeAH@", Server/binary>>, Stanza = escalus_stanza:from(escalus_stanza:chat_to_short_jid(Bob, Body), From), Res = send_stanza(exml:to_binary(Stanza), Config), - ?assertEqual(<<"unknown_user">>, get_err_code(Res)), - ?assertEqual(<<"Given user does not exist">>, get_err_msg(Res)). + ?assertEqual(<<"unknown_sender">>, get_err_code(Res)), + ?assertEqual(<<"Sender's account does not exist">>, get_err_msg(Res)). admin_send_stanza_from_unknown_domain(Config) -> escalus:fresh_story_with_config(Config, [{bob, 1}], @@ -324,8 +322,8 @@ admin_send_stanza_from_unknown_domain_story(Config, Bob) -> From = <<"YeeeAH@oopsie">>, Stanza = escalus_stanza:from(escalus_stanza:chat_to_short_jid(Bob, Body), From), Res = send_stanza(exml:to_binary(Stanza), Config), - ?assertEqual(<<"unknown_domain">>, get_err_code(Res)), - ?assertEqual(<<"Given domain does not exist">>, get_err_msg(Res)). + ?assertEqual(<<"unknown_sender">>, get_err_code(Res)), + ?assertEqual(<<"Sender's account does not exist">>, get_err_msg(Res)). admin_get_last_messages(Config) -> escalus:fresh_story_with_config(Config, [{alice, 1}, {bob, 1}], @@ -498,5 +496,5 @@ check_stanza_map(#{<<"sender">> := SenderJID, spoofed_error(Call, Response) -> null = graphql_helper:get_err_value([data, stanza, Call], Response), - ?assertEqual(<<"Sending from this JID is not allowed">>, get_err_msg(Response)), - ?assertEqual(<<"bad_from_jid">>, get_err_code(Response)). + ?assertEqual(<<"Sender's JID is different from the user's JID">>, get_err_msg(Response)), + ?assertEqual(<<"invalid_sender">>, get_err_code(Response)). diff --git a/big_tests/tests/rest_SUITE.erl b/big_tests/tests/rest_SUITE.erl index 811048981a0..95e19ff5ea2 100644 --- a/big_tests/tests/rest_SUITE.erl +++ b/big_tests/tests/rest_SUITE.erl @@ -267,9 +267,9 @@ message_errors(Config) -> send_message_bin(AliceJID, <<"@noway">>), {?BAD_REQUEST, <<"Invalid sender JID">>} = send_message_bin(<<"@noway">>, BobJID), - {?BAD_REQUEST, <<"Unknown user">>} = + {?BAD_REQUEST, <<"Sender's account does not exist">>} = send_message_bin(<<"baduser@", (domain())/binary>>, BobJID), - {?BAD_REQUEST, <<"Unknown domain">>} = + {?BAD_REQUEST, <<"Sender's account does not exist">>} = send_message_bin(<<"baduser@baddomain">>, BobJID). stanzas_are_sent_and_received(Config) -> @@ -297,9 +297,9 @@ stanza_errors(Config) -> send_stanza(extended_message([{<<"from">>, AliceJid}, {<<"to">>, <<"@invalid">>}])), {?BAD_REQUEST, <<"Invalid sender JID">>} = send_stanza(extended_message([{<<"from">>, <<"@invalid">>}, {<<"to">>, BobJid}])), - {?BAD_REQUEST, <<"Unknown domain">>} = + {?BAD_REQUEST, <<"Sender's account does not exist">>} = send_stanza(extended_message([{<<"from">>, <<"baduser@baddomain">>}, {<<"to">>, BobJid}])), - {?BAD_REQUEST, <<"Unknown user">>} = + {?BAD_REQUEST, <<"Sender's account does not exist">>} = send_stanza(extended_message([{<<"from">>, UnknownJid}, {<<"to">>, BobJid}])), {?BAD_REQUEST, <<"Malformed stanza">>} = send_stanza(broken_message([{<<"from">>, AliceJid}, {<<"to">>, BobJid}])), diff --git a/src/graphql/admin/mongoose_graphql_stanza_admin_mutation.erl b/src/graphql/admin/mongoose_graphql_stanza_admin_mutation.erl index 44d30afe2f8..87a51a3221f 100644 --- a/src/graphql/admin/mongoose_graphql_stanza_admin_mutation.erl +++ b/src/graphql/admin/mongoose_graphql_stanza_admin_mutation.erl @@ -6,8 +6,8 @@ -ignore_xref([execute/4]). -include("../mongoose_graphql_types.hrl"). --include("mongoose_logger.hrl"). --include("jlib.hrl"). + +-import(mongoose_graphql_helper, [format_result/2]). execute(_Ctx, _Obj, <<"sendMessage">>, Args) -> send_message(Args); @@ -17,16 +17,14 @@ execute(_Ctx, _Obj, <<"sendStanza">>, Args) -> send_stanza(Args). send_message(#{<<"from">> := From, <<"to">> := To, <<"body">> := Body}) -> - Packet = mongoose_stanza_helper:build_message( - jid:to_binary(From), jid:to_binary(To), Body), - mongoose_stanza_helper:route(From, To, Packet, true). + Res = mongoose_stanza_api:send_chat_message(null, From, To, Body), + format_result(Res, #{from => jid:to_binary(From)}). -send_message_headline(Args = #{<<"from">> := From, <<"to">> := To}) -> - Packet = mongoose_stanza_helper:build_message_with_headline( - jid:to_binary(From), jid:to_binary(To), Args), - mongoose_stanza_helper:route(From, To, Packet, true). +send_message_headline(#{<<"from">> := From, <<"to">> := To, + <<"body">> := Body, <<"subject">> := Subject}) -> + Res = mongoose_stanza_api:send_headline_message(null, From, To, Body, Subject), + format_result(Res, #{from => jid:to_binary(From)}). send_stanza(#{<<"stanza">> := Packet}) -> - From = jid:from_binary(exml_query:attr(Packet, <<"from">>)), - To = jid:from_binary(exml_query:attr(Packet, <<"to">>)), - mongoose_stanza_helper:route(From, To, Packet, true). + Res = mongoose_stanza_api:send_stanza(null, Packet), + format_result(Res, #{}). diff --git a/src/graphql/mongoose_graphql_helper.erl b/src/graphql/mongoose_graphql_helper.erl index bd446473fd3..d5101b0f80f 100644 --- a/src/graphql/mongoose_graphql_helper.erl +++ b/src/graphql/mongoose_graphql_helper.erl @@ -15,7 +15,7 @@ OutResult :: {ok, binary() | integer()} | {error, resolver_error()}. format_result(Result, Context) -> case Result of - {ok, Val} when is_integer(Val) -> {ok, Val}; + {ok, Val} when is_integer(Val) orelse is_map(Val) -> {ok, Val}; {ok, Msg} -> {ok, iolist_to_binary(Msg)}; {ErrCode, Msg} -> make_error(ErrCode, Msg, Context) end. diff --git a/src/graphql/user/mongoose_graphql_stanza_user_mutation.erl b/src/graphql/user/mongoose_graphql_stanza_user_mutation.erl index 74972ed6140..fa1b2083a9d 100644 --- a/src/graphql/user/mongoose_graphql_stanza_user_mutation.erl +++ b/src/graphql/user/mongoose_graphql_stanza_user_mutation.erl @@ -6,8 +6,8 @@ -ignore_xref([execute/4]). -include("../mongoose_graphql_types.hrl"). --include("mongoose_logger.hrl"). --include("jlib.hrl"). + +-import(mongoose_graphql_helper, [format_result/2]). execute(Ctx, _Obj, <<"sendMessage">>, Args) -> send_message(Ctx, Args); @@ -16,44 +16,15 @@ execute(Ctx, _Obj, <<"sendMessageHeadLine">>, Args) -> execute(Ctx, _Obj, <<"sendStanza">>, Args) -> send_stanza(Ctx, Args). -send_message(Ctx, Args) -> - with_from(Ctx, Args, fun send_message2/1). - -send_message_headline(Ctx, Args) -> - with_from(Ctx, Args, fun send_message_headline2/1). - -send_message2(#{<<"from">> := From, <<"to">> := To, <<"body">> := Body}) -> - Packet = mongoose_stanza_helper:build_message(jid:to_binary(From), jid:to_binary(To), Body), - %% SkipAuth = false, because we already checked if From exists - mongoose_stanza_helper:route(From, To, Packet, false). +send_message(#{user := User}, #{<<"from">> := From, <<"to">> := To, <<"body">> := Body}) -> + Res = mongoose_stanza_api:send_chat_message(User, From, To, Body), + format_result(Res, #{}). -send_message_headline2(Args = #{<<"from">> := From, <<"to">> := To}) -> - Packet = mongoose_stanza_helper:build_message_with_headline( - jid:to_binary(From), jid:to_binary(To), Args), - mongoose_stanza_helper:route(From, To, Packet, false). +send_message_headline(#{user := User}, #{<<"from">> := From, <<"to">> := To, <<"body">> := Body, + <<"subject">> := Subject}) -> + Res = mongoose_stanza_api:send_headline_message(User, From, To, Body, Subject), + format_result(Res, #{}). send_stanza(#{user := User}, #{<<"stanza">> := Packet}) -> - From = jid:from_binary(exml_query:attr(Packet, <<"from">>)), - To = jid:from_binary(exml_query:attr(Packet, <<"to">>)), - case jid:are_bare_equal(User, From) of - true -> - mongoose_stanza_helper:route(From, To, Packet, false); - false -> - {error, #{what => bad_from_jid}} - end. - -with_from(_Ctx = #{user := User}, Args, Next) -> - case maps:get(<<"from">>, Args, null) of - null -> - Next(Args#{<<"from">> => User}); - From -> - case jid:are_bare_equal(User, From) of - true -> - %% We still can allow a custom resource - Next(Args#{<<"from">> => From}); - false -> - ?LOG_ERROR(#{what => bad_from_jid, - user_jid => User, from_jid => From}), - {error, #{what => bad_from_jid}} - end - end. + Res = mongoose_stanza_api:send_stanza(User, Packet), + format_result(Res, #{}). diff --git a/src/mam/mod_mam_utils.erl b/src/mam/mod_mam_utils.erl index f9e8cc213f8..8da1275314b 100644 --- a/src/mam/mod_mam_utils.erl +++ b/src/mam/mod_mam_utils.erl @@ -10,7 +10,6 @@ %% UID -export([get_or_generate_mam_id/1, - get_mam_id_ext/1, generate_message_id/1, encode_compact_uuid/2, decode_compact_uuid/1, @@ -177,15 +176,6 @@ get_or_generate_mam_id(Acc) -> mod_mam_utils:external_binary_to_mess_id(ExtMessId) end. --spec get_mam_id_ext(mongoose_acc:t()) -> binary(). -get_mam_id_ext(Acc) -> - case mongoose_acc:get(mam, mam_id, undefined, Acc) of - undefined -> - <<>>; - ExtMessId -> - ExtMessId - end. - -spec generate_message_id(integer()) -> integer(). generate_message_id(CandidateStamp) -> {ok, NodeId} = ejabberd_node_id:node_id(), diff --git a/src/mongoose_admin_api/mongoose_admin_api_messages.erl b/src/mongoose_admin_api/mongoose_admin_api_messages.erl index 3455f78cd96..a1e20d9a7b5 100644 --- a/src/mongoose_admin_api/mongoose_admin_api_messages.erl +++ b/src/mongoose_admin_api/mongoose_admin_api_messages.erl @@ -78,15 +78,11 @@ handle_post(Req, State) -> From = get_caller(Args), To = get_to(Args), Body = get_body(Args), - Packet = mongoose_stanza_helper:build_message( - jid:to_binary(From), jid:to_binary(To), Body), - case mongoose_stanza_helper:route(From, To, Packet, true) of - {error, #{what := unknown_domain}} -> - throw_error(bad_request, <<"Unknown domain">>); - {error, #{what := unknown_user}} -> - throw_error(bad_request, <<"Unknown user">>); + case mongoose_stanza_api:send_chat_message(null, From, To, Body) of {ok, _} -> - {true, Req, State} + {true, Req, State}; + {_Error, Msg} -> + throw_error(bad_request, Msg) end. -spec row_to_map(mod_mam:message_row()) -> map(). diff --git a/src/mongoose_admin_api/mongoose_admin_api_stanzas.erl b/src/mongoose_admin_api/mongoose_admin_api_stanzas.erl index d892f0da8a8..d697e79c438 100644 --- a/src/mongoose_admin_api/mongoose_admin_api_stanzas.erl +++ b/src/mongoose_admin_api/mongoose_admin_api_stanzas.erl @@ -50,15 +50,11 @@ from_json(Req, State) -> handle_post(Req, State) -> Args = parse_body(Req), Stanza = get_stanza(Args), - From = get_from_jid(Stanza), - To = get_to_jid(Stanza), - case mongoose_stanza_helper:route(From, To, Stanza, true) of - {error, #{what := unknown_domain}} -> - throw_error(bad_request, <<"Unknown domain">>); - {error, #{what := unknown_user}} -> - throw_error(bad_request, <<"Unknown user">>); + case mongoose_stanza_api:send_stanza(null, Stanza) of {ok, _} -> - {true, Req, State} + {true, Req, State}; + {_Error, Msg} -> + throw_error(bad_request, Msg) end. get_stanza(#{stanza := BinStanza}) -> @@ -68,26 +64,5 @@ get_stanza(#{stanza := BinStanza}) -> {error, _} -> throw_error(bad_request, <<"Malformed stanza">>) end; -get_stanza(#{}) -> throw_error(bad_request, <<"Missing stanza">>). - -get_from_jid(Stanza) -> - case exml_query:attr(Stanza, <<"from">>) of - undefined -> - throw_error(bad_request, <<"Missing sender JID">>); - JidBin -> - case jid:from_binary(JidBin) of - error -> throw_error(bad_request, <<"Invalid sender JID">>); - Jid -> Jid - end - end. - -get_to_jid(Stanza) -> - case exml_query:attr(Stanza, <<"to">>) of - undefined -> - throw_error(bad_request, <<"Missing recipient JID">>); - JidBin -> - case jid:from_binary(JidBin) of - error -> throw_error(bad_request, <<"Invalid recipient JID">>); - Jid -> Jid - end - end. +get_stanza(#{}) -> + throw_error(bad_request, <<"Missing stanza">>). diff --git a/src/mongoose_client_api/mongoose_client_api_messages.erl b/src/mongoose_client_api/mongoose_client_api_messages.erl index c56b8c3b05a..e3f5de1b6f3 100644 --- a/src/mongoose_client_api/mongoose_client_api_messages.erl +++ b/src/mongoose_client_api/mongoose_client_api_messages.erl @@ -78,14 +78,11 @@ handle_get(Req, State = #{jid := OwnerJid}) -> Resp = [make_json_msg(Msg, MAMId) || #{id := MAMId, packet := Msg} <- Rows], {jiffy:encode(Resp), Req, State}. -handle_post(Req, State = #{jid := From}) -> +handle_post(Req, State = #{jid := UserJid}) -> Args = parse_body(Req), To = get_to(Args), Body = get_body(Args), - Packet = mongoose_stanza_helper:build_message(jid:to_binary(From), jid:to_binary(To), Body), - {ok, _} = mongoose_stanza_helper:route(From, To, Packet, true), - Id = exml_query:attr(Packet, <<"id">>), - Resp = #{<<"id">> => Id}, + {ok, Resp} = mongoose_stanza_api:send_chat_message(UserJid, null, To, Body), Req2 = cowboy_req:set_resp_body(jiffy:encode(Resp), Req), {true, Req2, State}. diff --git a/src/mongoose_stanza_api.erl b/src/mongoose_stanza_api.erl index fa3f09108d2..d705d7fb11a 100644 --- a/src/mongoose_stanza_api.erl +++ b/src/mongoose_stanza_api.erl @@ -1,15 +1,92 @@ -module(mongoose_stanza_api). --export([lookup_recent_messages/4]). +-export([send_chat_message/4, send_headline_message/5, send_stanza/2, lookup_recent_messages/4]). -include("jlib.hrl"). -include("mongoose_rsm.hrl"). +-spec send_chat_message(jid:jid() | null, jid:jid() | null, jid:jid(), binary()) -> + {unknown_sender | invalid_sender, iodata()} | {ok, map()}. +send_chat_message(User, From, To, Body) -> + M = #{user => User, from => From, to => To, body => Body}, + fold(M, [fun get_sender_jid/1, fun prepare_chat_message/1, fun send/1]). + +-spec send_headline_message(jid:jid() | null, jid:jid() | null, jid:jid(), + binary() | null, binary() | null) -> + {unknown_sender | invalid_sender | no_sender | + invalid_recipient | no_recipient, iodata()} | {ok, map()}. +send_headline_message(User, From, To, Body, Subject) -> + M = #{user => User, from => From, to => To, body => Body, subject => Subject}, + fold(M, [fun get_sender_jid/1, fun prepare_headline_message/1, fun send/1]). + +-spec send_stanza(jid:jid() | null, exml:element()) -> + {unknown_sender | invalid_sender, iodata()} | {ok, map()}. +send_stanza(User, Stanza) -> + M = #{user => User, stanza => Stanza}, + fold(M, [fun get_from_jid/1, fun get_to_jid/1, fun get_sender_jid/1, + fun prepare_stanza/1, fun send/1]). + +get_sender_jid(M = #{user := null, from := From = #jid{}}) -> + case ejabberd_auth:does_user_exist(From) of + true -> + M; + false -> + {unknown_sender, <<"Sender's account does not exist">>} + end; +get_sender_jid(M = #{user := User = #jid{}, from := null}) -> + M#{from => User}; +get_sender_jid(M = #{user := User = #jid{}, from := From = #jid{}}) -> + case jid:are_bare_equal(User, From) of + true -> + M; + false -> + {invalid_sender, <<"Sender's JID is different from the user's JID">>} + end. + +send(#{from := #jid{lserver = SenderDomain} = From, to := To, stanza := Stanza}) -> + {ok, HostType} = mongoose_domain_api:get_domain_host_type(SenderDomain), + mongoose_stanza_helper:route(HostType, SenderDomain, From, To, Stanza). + +get_from_jid(M = #{stanza := Stanza}) -> + case exml_query:attr(Stanza, <<"from">>) of + undefined -> + {no_sender, <<"Missing sender JID">>}; + JidBin -> + case jid:from_binary(JidBin) of + error -> {invalid_sender, <<"Invalid sender JID">>}; + Jid -> M#{from => Jid} + end + end. + +get_to_jid(M = #{stanza := Stanza}) -> + case exml_query:attr(Stanza, <<"to">>) of + undefined -> + {no_recipient, <<"Missing recipient JID">>}; + JidBin -> + case jid:from_binary(JidBin) of + error -> {invalid_recipient, <<"Invalid recipient JID">>}; + Jid -> M#{to => Jid} + end + end. + +prepare_chat_message(M = #{from := From, to := To, body := Body}) -> + FromBin = jid:to_binary(From), + ToBin = jid:to_binary(To), + M#{stanza => mongoose_stanza_helper:build_message(FromBin, ToBin, Body)}. + +prepare_headline_message(M = #{from := From, to := To, body := Body, subject := Subject}) -> + FromBin = jid:to_binary(From), + ToBin = jid:to_binary(To), + M#{stanza => mongoose_stanza_helper:build_message_with_headline(FromBin, ToBin, Body, Subject)}. + +prepare_stanza(M = #{stanza := Stanza}) -> + M#{stanza := mongoose_stanza_helper:ensure_id(Stanza)}. + %% TODO fix error handling, do not crash for non-existing users %% Before is in microseconds -spec lookup_recent_messages( ArcJID :: jid:jid(), With :: jid:jid() | undefined, - Before :: mod_mam:unix_timestamp() | undefined, + Before :: mod_mam:unix_timestamp() | undefined, % microseconds Limit :: non_neg_integer()) -> [mod_mam:message_row()]. lookup_recent_messages(_, _, _, Limit) when Limit > 500 -> @@ -37,3 +114,8 @@ lookup_recent_messages(ArcJID, WithJID, Before, Limit) -> R = mod_mam_pm:lookup_messages(HostType, Params), {ok, {_, _, L}} = R, L. + +fold({_, _} = Result, _) -> + Result; +fold(M, [Step | Rest]) when is_map(M) -> + fold(Step(M), Rest). diff --git a/src/mongoose_stanza_helper.erl b/src/mongoose_stanza_helper.erl index ea1025c4f1c..53a6e2f1a34 100644 --- a/src/mongoose_stanza_helper.erl +++ b/src/mongoose_stanza_helper.erl @@ -1,8 +1,9 @@ -module(mongoose_stanza_helper). -export([build_message/3]). --export([build_message_with_headline/3]). +-export([build_message_with_headline/4]). +-export([ensure_id/1]). -export([get_last_messages/4]). --export([route/4]). +-export([route/5]). -include("jlib.hrl"). -include("mongoose_logger.hrl"). @@ -10,24 +11,23 @@ -spec build_message(From :: binary(), To :: binary(), Body :: binary()) -> exml:element(). build_message(From, To, Body) -> #xmlel{name = <<"message">>, - attrs = [{<<"type">>, <<"chat">>}, - {<<"id">>, mongoose_bin:gen_from_crypto()}, - {<<"from">>, From}, - {<<"to">>, To}], + attrs = add_id([{<<"type">>, <<"chat">>}, {<<"from">>, From}, {<<"to">>, To}]), children = [#xmlel{name = <<"body">>, children = [#xmlcdata{content = Body}]}] }. -build_message_with_headline(FromBin, ToBin, - #{<<"body">> := Body, <<"subject">> := Subject}) -> +build_message_with_headline(From, To, Body, Subject) -> Children = maybe_cdata_elem(<<"subject">>, Subject) ++ maybe_cdata_elem(<<"body">>, Body), - Attrs = [{<<"type">>, <<"headline">>}, - {<<"id">>, mongoose_bin:gen_from_crypto()}, - {<<"from">>, FromBin}, - {<<"to">>, ToBin}], + Attrs = add_id([{<<"type">>, <<"headline">>}, {<<"from">>, From}, {<<"to">>, To}]), #xmlel{name = <<"message">>, attrs = Attrs, children = Children}. +ensure_id(Stanza) -> + case get_id(Stanza) of + null -> Stanza#xmlel{attrs = add_id(Stanza#xmlel.attrs)}; + _ -> Stanza + end. + maybe_cdata_elem(_, null) -> []; maybe_cdata_elem(_, <<>>) -> []; maybe_cdata_elem(Name, Text) when is_binary(Text) -> @@ -52,31 +52,27 @@ null_as_undefined(null) -> undefined; null_as_undefined(Value) -> Value. -spec row_to_map(mod_mam:message_row()) -> {ok, map()}. -row_to_map(#{id := Id, jid := From, packet := Msg}) -> - {Microseconds, _} = mod_mam_utils:decode_compact_uuid(Id), - StanzaID = mod_mam_utils:mess_id_to_external_binary(Id), +row_to_map(#{id := MAMId, jid := From, packet := Msg}) -> + {Microseconds, _} = mod_mam_utils:decode_compact_uuid(MAMId), Map = #{<<"sender">> => From, <<"timestamp">> => Microseconds, - <<"stanza_id">> => StanzaID, <<"stanza">> => Msg}, + <<"stanza_id">> => get_id(Msg), <<"stanza">> => Msg}, {ok, Map}. --spec route(From :: jid:jid(), To :: jid:jid(), - Packet :: exml:element(), SkipAuth :: boolean()) -> +-spec route(mongoosim:host_type(), jid:lserver(), From :: jid:jid(), To :: jid:jid(), + Packet :: exml:element()) -> {ok, map()} | {error, term()}. -route(From = #jid{lserver = LServer}, To, Packet, SkipAuth) -> - case mongoose_graphql_helper:check_user(From, SkipAuth) of - {ok, HostType} -> - do_route(HostType, LServer, From, To, Packet); - Error -> - Error - end. - -do_route(HostType, LServer, From, To, Packet) -> - %% Based on mod_commands:do_send_packet/3 +route(HostType, LServer, From, To, Packet) -> Acc = mongoose_acc:new(#{location => ?LOCATION, - host_type => HostType, - lserver => LServer, - element => Packet}), + host_type => HostType, + lserver => LServer, + element => Packet}), Acc1 = mongoose_hooks:user_send_packet(Acc, From, To, Packet), - Acc2 = ejabberd_router:route(From, To, Acc1), - MessID = mod_mam_utils:get_mam_id_ext(Acc2), - {ok, #{ <<"id">> => MessID }}. + ejabberd_router:route(From, To, Acc1), + {ok, #{<<"id">> => get_id(Packet)}}. + +add_id(Attrs) -> + [{<<"id">>, mongoose_bin:gen_from_crypto()} | Attrs]. + +-spec get_id(exml:element()) -> binary() | null. +get_id(Stanza) -> + exml_query:attr(Stanza, <<"id">>, null).