1 |
|
%% @doc Provide an interface for frontends (like graphql or ctl) to manage private. |
2 |
|
-module(mod_private_api). |
3 |
|
|
4 |
|
-include("mongoose.hrl"). |
5 |
|
-include("ejabberd_commands.hrl"). |
6 |
|
-include("jlib.hrl"). |
7 |
|
-include_lib("exml/include/exml.hrl"). |
8 |
|
|
9 |
|
-export([private_get/3, private_set/2]). |
10 |
|
|
11 |
|
-spec private_get(jid:jid(), binary(), binary()) -> {Res, iodata()} when |
12 |
|
Res :: ok | not_found. |
13 |
|
private_get(JID, Element, Ns) -> |
14 |
6 |
case ejabberd_auth:does_user_exist(JID) of |
15 |
|
true -> |
16 |
5 |
{ok, do_private_get(JID, Element, Ns)}; |
17 |
|
false -> |
18 |
1 |
{not_found, io_lib:format("User ~s does not exist", [jid:to_binary(JID)])} |
19 |
|
end. |
20 |
|
|
21 |
|
-spec private_set(jid:jid(), ElementString :: binary()) -> {Res, iolist()} when |
22 |
|
Res :: ok | not_found | not_loaded | parse_error. |
23 |
|
private_set(JID, ElementString) -> |
24 |
6 |
case exml:parse(ElementString) of |
25 |
|
{error, Error} -> |
26 |
1 |
String = io_lib:format("Error found parsing the element:~n ~p~nError: ~p~n", |
27 |
|
[ElementString, Error]), |
28 |
1 |
{parse_error, String}; |
29 |
|
{ok, Xml} -> |
30 |
5 |
do_private_set(JID, Xml) |
31 |
|
end. |
32 |
|
|
33 |
|
do_private_get(JID, Element, Ns) -> |
34 |
5 |
{ok, HostType} = mongoose_domain_api:get_domain_host_type(JID#jid.lserver), |
35 |
5 |
Xml = #xmlel{ name = Element, attrs = [{<<"xmlns">>, Ns}]}, |
36 |
5 |
{_, ResIq} = send_iq(get, Xml, JID, HostType), |
37 |
5 |
[#xmlel{ name = <<"query">>, |
38 |
|
attrs = [{<<"xmlns">>, ?NS_PRIVATE}], |
39 |
|
children = [SubEl] }] = ResIq#iq.sub_el, |
40 |
5 |
exml:to_binary(SubEl). |
41 |
|
|
42 |
|
do_private_set(JID, Xml) -> |
43 |
5 |
case ejabberd_auth:does_user_exist(JID) of |
44 |
|
true -> |
45 |
4 |
do_private_set2(JID, Xml); |
46 |
|
false -> |
47 |
1 |
{not_found, io_lib:format("User ~s does not exist", [jid:to_binary(JID)])} |
48 |
|
end. |
49 |
|
|
50 |
|
do_private_set2(#jid{lserver = Domain} = JID, Xml) -> |
51 |
4 |
{ok, HostType} = mongoose_domain_api:get_domain_host_type(Domain), |
52 |
4 |
case is_private_module_loaded(HostType) of |
53 |
|
true -> |
54 |
4 |
send_iq(set, Xml, JID, HostType), |
55 |
4 |
{ok, ""}; |
56 |
|
false -> |
57 |
:-( |
{not_loaded, io_lib:format("Module mod_private is not loaded on domain ~s", [Domain])} |
58 |
|
end. |
59 |
|
|
60 |
|
-spec is_private_module_loaded(jid:server()) -> true | false. |
61 |
|
is_private_module_loaded(Server) -> |
62 |
4 |
lists:member(mod_private, gen_mod:loaded_modules(Server)). |
63 |
|
|
64 |
|
send_iq(Method, Xml, From = To = _JID, HostType) -> |
65 |
9 |
IQ = {iq, <<"">>, Method, ?NS_PRIVATE, <<"">>, |
66 |
|
#xmlel{ name = <<"query">>, |
67 |
|
attrs = [{<<"xmlns">>, ?NS_PRIVATE}], |
68 |
|
children = [Xml] } }, |
69 |
9 |
Acc = mongoose_acc:new(#{ location => ?LOCATION, |
70 |
|
from_jid => From, |
71 |
|
to_jid => To, |
72 |
|
lserver => From#jid.lserver, |
73 |
|
host_type => HostType, |
74 |
|
element => jlib:iq_to_xml(IQ) }), |
75 |
9 |
mod_private:process_iq(Acc, From, To, IQ, #{}). |