./ct_report/coverage/adhoc.COVER.html

1 %%%----------------------------------------------------------------------
2 %%% File : adhoc.erl
3 %%% Author : Magnus Henoch <henoch@dtek.chalmers.se>
4 %%% Purpose : Provide helper functions for ad-hoc commands (XEP-0050)
5 %%% Created : 31 Oct 2005 by Magnus Henoch <henoch@dtek.chalmers.se>
6 %%%
7 %%%
8 %%% ejabberd, Copyright (C) 2002-2011 ProcessOne
9 %%%
10 %%% This program is free software; you can redistribute it and/or
11 %%% modify it under the terms of the GNU General Public License as
12 %%% published by the Free Software Foundation; either version 2 of the
13 %%% License, or (at your option) any later version.
14 %%%
15 %%% This program is distributed in the hope that it will be useful,
16 %%% but WITHOUT ANY WARRANTY; without even the implied warranty of
17 %%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 %%% General Public License for more details.
19 %%%
20 %%% You should have received a copy of the GNU General Public License
21 %%% along with this program; if not, write to the Free Software
22 %%% Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 %%%
24 %%%----------------------------------------------------------------------
25
26 -module(adhoc).
27 -author('henoch@dtek.chalmers.se').
28 -xep([{xep, 50}, {version, "1.2"}]).
29 -export([parse_request/1,
30 produce_response/2,
31 produce_response/4,
32 produce_response/1]).
33
34 -include("mongoose.hrl").
35 -include("jlib.hrl").
36 -include("adhoc.hrl").
37
38 -type request() :: #adhoc_request{}.
39 -type response() :: #adhoc_response{}.
40
41 -export_type([request/0, response/0]).
42
43 %% @doc Parse an ad-hoc request. Return either an adhoc_request record or
44 %% an {error, ErrorType} tuple.
45 -spec parse_request(jlib:iq()) -> request() | {error, exml:element()}.
46 parse_request(#iq{type = set, lang = Lang, sub_el = SubEl, xmlns = ?NS_COMMANDS}) ->
47 1 ?LOG_DEBUG(#{what => adhoc_parse_request,
48 text => <<"entering parse_request...">>,
49 1 sub_el => SubEl}),
50 1 Node = xml:get_tag_attr_s(<<"node">>, SubEl),
51 1 SessionID = xml:get_tag_attr_s(<<"sessionid">>, SubEl),
52 1 Action = xml:get_tag_attr_s(<<"action">>, SubEl),
53 1 XData = find_xdata_el(SubEl),
54 1 #xmlel{children = AllEls} = SubEl,
55 1 Others = case XData of
56 false ->
57 1 AllEls;
58 _ ->
59
:-(
lists:delete(XData, AllEls)
60 end,
61
62 1 #adhoc_request{lang = Lang,
63 node = Node,
64 session_id = SessionID,
65 action = Action,
66 xdata = XData,
67 others = Others};
68 parse_request(_) ->
69
:-(
{error, mongoose_xmpp_errors:bad_request()}.
70
71 %% @doc Borrowed from mod_vcard.erl
72 -spec find_xdata_el(exml:element()) -> false | exml:element().
73 find_xdata_el(#xmlel{children = SubEls}) ->
74 1 find_xdata_el1(SubEls).
75
76 %% @private
77 find_xdata_el1([]) ->
78 1 false;
79 find_xdata_el1([XE = #xmlel{attrs = Attrs} | Els]) ->
80
:-(
case xml:get_attr_s(<<"xmlns">>, Attrs) of
81 ?NS_XDATA ->
82
:-(
XE;
83 _ ->
84
:-(
find_xdata_el1(Els)
85 end;
86 find_xdata_el1([_ | Els]) ->
87
:-(
find_xdata_el1(Els).
88
89 %% @doc Produce a <command/> node to use as response from an adhoc_response
90 %% record, filling in values for language, node and session id from
91 %% the request.
92 -spec produce_response(request(), response() | atom()) -> #xmlel{}.
93 produce_response(Request, Status) when is_atom(Status) ->
94
:-(
produce_response(Request, Status, <<>>, []);
95 produce_response(#adhoc_request{lang = Lang,
96 node = Node,
97 session_id = SessionID},
98 Response) ->
99
:-(
produce_response(Response#adhoc_response{lang = Lang,
100 node = Node,
101 session_id = SessionID}).
102
103 %% @doc Produce a <command/> node to use as response from an adhoc_response
104 %% record, filling in values for language, node and session id from
105 %% the request.
106 -spec produce_response(request(), Status :: atom(), DefaultAction :: binary(),
107 Elements :: [exml:element()]) -> exml:element().
108 produce_response(Request, Status, DefaultAction, Elements) ->
109
:-(
#adhoc_request{lang = Lang, node = Node, session_id = SessionID} = Request,
110
:-(
produce_response(#adhoc_response{lang = Lang, node = Node, session_id = SessionID,
111 status = Status, default_action = DefaultAction,
112 elements = Elements}).
113
114
115 %% @doc Produce a <command/> node to use as response from an adhoc_response
116 %% record.
117 -spec produce_response(response()) -> exml:element().
118 produce_response(#adhoc_response{lang = _Lang,
119 node = Node,
120 session_id = ProvidedSessionID,
121 status = Status,
122 default_action = DefaultAction,
123 actions = Actions,
124 notes = Notes,
125 elements = Elements}) ->
126 1 SessionID = if is_binary(ProvidedSessionID), ProvidedSessionID /= <<"">> ->
127
:-(
ProvidedSessionID;
128 true ->
129 1 USec = os:system_time(microsecond),
130 1 TS = calendar:system_time_to_rfc3339(USec, [{offset, "Z"},
131 {unit, microsecond}]),
132 1 list_to_binary(TS)
133 end,
134 1 ActionsEls = case Actions of
135 [] ->
136 1 [];
137 _ ->
138
:-(
ActionsElAttrs = case DefaultAction of
139
:-(
<<"">> -> [];
140
:-(
_ -> [{<<"execute">>, DefaultAction}]
141 end,
142
:-(
[#xmlel{name = <<"actions">>, attrs = ActionsElAttrs,
143
:-(
children = [#xmlel{name = Action} || Action <- Actions]}]
144 end,
145 1 NotesEls = lists:map(fun({Type, Text}) ->
146 1 #xmlel{name = <<"note">>,
147 attrs = [{<<"type">>, Type}],
148 children = [#xmlcdata{content = Text}]}
149 end, Notes),
150 1 #xmlel{name = <<"command">>,
151 attrs = [{<<"xmlns">>, ?NS_COMMANDS},
152 {<<"sessionid">>, SessionID},
153 {<<"node">>, Node},
154 {<<"status">>, list_to_binary(atom_to_list(Status))}],
155 children = ActionsEls ++ NotesEls ++ Elements}.
Line Hits Source