./ct_report/coverage/mongoose_admin_api_muc_light.COVER.html

1 -module(mongoose_admin_api_muc_light).
2
3 -behaviour(mongoose_admin_api).
4 -export([routes/1]).
5
6 -behaviour(cowboy_rest).
7 -export([init/2,
8 is_authorized/2,
9 content_types_accepted/2,
10 allowed_methods/2,
11 from_json/2,
12 delete_resource/2]).
13
14 -ignore_xref([to_json/2, from_json/2]).
15
16 -import(mongoose_admin_api, [try_handle_request/3, throw_error/2, parse_body/1, resource_created/4]).
17
18 -type req() :: cowboy_req:req().
19 -type state() :: mongoose_admin_api:state().
20
21 -spec routes(state()) -> mongoose_http_handler:routes().
22 routes(State) ->
23 4 [{"/muc-lights/:domain", ?MODULE, State},
24 {"/muc-lights/:domain/:id/participants", ?MODULE, State#{suffix => participants}},
25 {"/muc-lights/:domain/:id/messages", ?MODULE, State#{suffix => messages}},
26 {"/muc-lights/:domain/:id/management", ?MODULE, State#{suffix => management}}].
27
28 -spec init(req(), state()) -> {cowboy_rest, req(), state()}.
29 init(Req, State) ->
30
:-(
mongoose_admin_api:init(Req, State).
31
32 -spec is_authorized(req(), state()) -> {true | {false, iodata()}, req(), state()}.
33 is_authorized(Req, State) ->
34
:-(
mongoose_admin_api:is_authorized(Req, State).
35
36 -spec content_types_accepted(req(), state()) ->
37 {[{{binary(), binary(), '*'}, atom()}], req(), state()}.
38 content_types_accepted(Req, State) ->
39
:-(
{[
40 {{<<"application">>, <<"json">>, '*'}, from_json}
41 ], Req, State}.
42
43 -spec allowed_methods(req(), state()) -> {[binary()], req(), state()}.
44 allowed_methods(Req, State) ->
45
:-(
{[<<"OPTIONS">>, <<"POST">>, <<"PUT">>, <<"DELETE">>], Req, State}.
46
47 %% @doc Called for a method of type "POST" and "PUT"
48 -spec from_json(req(), state()) -> {stop, req(), state()}.
49 from_json(Req, State) ->
50
:-(
F = case cowboy_req:method(Req) of
51
:-(
<<"POST">> -> fun handle_post/2;
52
:-(
<<"PUT">> -> fun handle_put/2
53 end,
54
:-(
try_handle_request(Req, State, F).
55
56 %% @doc Called for a method of type "DELETE"
57 -spec delete_resource(req(), state()) -> {true | stop, req(), state()}.
58 delete_resource(Req, State) ->
59
:-(
try_handle_request(Req, State, fun handle_delete/2).
60
61 %% Internal functions
62
63 handle_post(Req, #{suffix := participants} = State) ->
64
:-(
Bindings = cowboy_req:bindings(Req),
65
:-(
RoomJid = get_room_jid(Bindings),
66
:-(
Args = parse_body(Req),
67
:-(
SenderJid = get_sender_jid(Args),
68
:-(
RecipientJid = get_recipient_jid(Args),
69
:-(
case mod_muc_light_api:invite_to_room(RoomJid, SenderJid, RecipientJid) of
70 {ok, _} ->
71
:-(
{stop, Req, State};
72 {muc_server_not_found, Msg} ->
73
:-(
throw_error(not_found, Msg);
74 {room_not_found, Msg} ->
75
:-(
throw_error(not_found, Msg);
76 {user_not_found, Msg} ->
77
:-(
throw_error(bad_request, Msg);
78 {not_room_member, Msg} ->
79
:-(
throw_error(denied, Msg)
80 end;
81 handle_post(Req, #{suffix := messages} = State) ->
82
:-(
Bindings = cowboy_req:bindings(Req),
83
:-(
RoomJid = get_room_jid(Bindings),
84
:-(
Args = parse_body(Req),
85
:-(
SenderJid = get_from_jid(Args),
86
:-(
Body = get_message_body(Args),
87
:-(
case mod_muc_light_api:send_message(RoomJid, SenderJid, Body) of
88 {ok, _} ->
89
:-(
{stop, Req, State};
90 {muc_server_not_found, Msg} ->
91
:-(
throw_error(not_found, Msg);
92 {room_not_found, Msg} ->
93
:-(
throw_error(not_found, Msg);
94 {user_not_found, Msg} ->
95
:-(
throw_error(bad_request, Msg);
96 {not_room_member, Msg} ->
97
:-(
throw_error(denied, Msg)
98 end;
99 handle_post(Req, State) ->
100
:-(
#{domain := MUCDomain} = cowboy_req:bindings(Req),
101
:-(
Args = parse_body(Req),
102
:-(
OwnerJid = get_owner_jid(Args),
103
:-(
RoomName = get_room_name(Args),
104
:-(
Subject = get_room_subject(Args),
105
:-(
Config = #{<<"roomname">> => RoomName, <<"subject">> => Subject},
106
:-(
case mod_muc_light_api:create_room(MUCDomain, OwnerJid, Config) of
107 {ok, #{jid := RoomJid}} ->
108
:-(
RoomJidBin = jid:to_binary(RoomJid),
109
:-(
Path = [cowboy_req:uri(Req), "/", RoomJidBin],
110
:-(
resource_created(Req, State, Path, RoomJidBin);
111 {user_not_found, Msg} ->
112
:-(
throw_error(bad_request, Msg);
113 {muc_server_not_found, Msg} ->
114
:-(
throw_error(not_found, Msg)
115 end.
116
117 handle_put(Req, State) ->
118
:-(
#{domain := MUCDomain} = cowboy_req:bindings(Req),
119
:-(
Args = parse_body(Req),
120
:-(
OwnerJid = get_owner_jid(Args),
121
:-(
RoomName = get_room_name(Args),
122
:-(
RoomId = get_room_id(Args),
123
:-(
Subject = get_room_subject(Args),
124
:-(
Config = #{<<"roomname">> => RoomName, <<"subject">> => Subject},
125
:-(
case mod_muc_light_api:create_room(MUCDomain, RoomId, OwnerJid, Config) of
126 {ok, #{jid := RoomJid}} ->
127
:-(
RoomJidBin = jid:to_binary(RoomJid),
128
:-(
Path = [cowboy_req:uri(Req), "/", RoomJidBin],
129
:-(
resource_created(Req, State, Path, RoomJidBin);
130 {muc_server_not_found, Msg} ->
131
:-(
throw_error(not_found, Msg);
132 {already_exists, Msg} ->
133
:-(
throw_error(denied, Msg)
134 end.
135
136 handle_delete(Req, #{suffix := management} = State) ->
137
:-(
Bindings = cowboy_req:bindings(Req),
138
:-(
RoomJid = get_room_jid(Bindings),
139
:-(
case mod_muc_light_api:delete_room(RoomJid) of
140 {ok, _} ->
141
:-(
{true, Req, State};
142 {muc_server_not_found, Msg} ->
143
:-(
throw_error(not_found, Msg);
144 {room_not_found, Msg} ->
145
:-(
throw_error(not_found, Msg)
146 end;
147 handle_delete(_Req, _State) ->
148
:-(
throw_error(not_found, ""). % Cowboy returns the same for unknown paths
149
150 get_owner_jid(#{owner := Owner}) ->
151
:-(
case jid:from_binary(Owner) of
152
:-(
error -> throw_error(bad_request, <<"Invalid owner JID">>);
153
:-(
OwnerJid -> OwnerJid
154 end;
155
:-(
get_owner_jid(#{}) -> throw_error(bad_request, <<"Missing owner JID">>).
156
157 get_room_jid(#{domain := MUCDomain} = Bindings) ->
158
:-(
RoomId = get_room_id(Bindings),
159
:-(
case jid:make_bare(RoomId, MUCDomain) of
160
:-(
error -> throw_error(bad_request, <<"Invalid room ID or domain name">>);
161
:-(
RoomJid -> RoomJid
162 end.
163
164
:-(
get_room_name(#{name := Name}) -> Name;
165
:-(
get_room_name(#{}) -> throw_error(bad_request, <<"Missing room name">>).
166
167
:-(
get_room_id(#{id := Id}) -> Id;
168
:-(
get_room_id(#{}) -> throw_error(bad_request, <<"Missing room ID">>).
169
170
:-(
get_room_subject(#{subject := Subject}) -> Subject;
171
:-(
get_room_subject(#{}) -> throw_error(bad_request, <<"Missing room subject">>).
172
173
:-(
get_message_body(#{body := Body}) -> Body;
174
:-(
get_message_body(#{}) -> throw_error(bad_request, <<"Missing message body">>).
175
176 get_from_jid(#{from := Sender}) ->
177
:-(
case jid:from_binary(Sender) of
178
:-(
error -> throw_error(bad_request, <<"Invalid sender JID">>);
179
:-(
SenderJid -> SenderJid
180 end;
181
:-(
get_from_jid(#{}) -> throw_error(bad_request, <<"Missing sender JID">>).
182
183 get_sender_jid(#{sender := Sender}) ->
184
:-(
case jid:from_binary(Sender) of
185
:-(
error -> throw_error(bad_request, <<"Invalid sender JID">>);
186
:-(
SenderJid -> SenderJid
187 end;
188
:-(
get_sender_jid(#{}) -> throw_error(bad_request, <<"Missing sender JID">>).
189
190 get_recipient_jid(#{recipient := Recipient}) ->
191
:-(
case jid:from_binary(Recipient) of
192
:-(
error -> throw_error(bad_request, <<"Invalid recipient JID">>);
193
:-(
RecipientJid -> RecipientJid
194 end;
195
:-(
get_recipient_jid(#{}) -> throw_error(bad_request, <<"Missing recipient JID">>).
Line Hits Source