./ct_report/coverage/mongoose_client_api_rooms.COVER.html

1 -module(mongoose_client_api_rooms).
2 -behaviour(cowboy_rest).
3
4 -export([trails/0]).
5
6 -export([init/2]).
7 -export([content_types_provided/2]).
8 -export([content_types_accepted/2]).
9 -export([is_authorized/2]).
10 -export([allowed_methods/2]).
11 -export([resource_exists/2]).
12 -export([assert_room_id_set/2]).
13
14 -export([to_json/2]).
15 -export([from_json/2]).
16
17 -ignore_xref([
18 from_json/2, to_json/2, trails/0
19 ]).
20
21 -include("mongoose.hrl").
22 -include("jlib.hrl").
23 -include_lib("exml/include/exml.hrl").
24
25 trails() ->
26 76 mongoose_client_api_rooms_doc:trails().
27
28 init(Req, Opts) ->
29 43 mongoose_client_api:init(Req, Opts).
30
31 is_authorized(Req, State) ->
32 43 mongoose_client_api:is_authorized(Req, State).
33
34 content_types_provided(Req, State) ->
35 90 {[
36 {{<<"application">>, <<"json">>, '*'}, to_json}
37 ], Req, State}.
38
39 content_types_accepted(Req, State) ->
40 62 {[
41 {{<<"application">>, <<"json">>, '*'}, from_json}
42 ], Req, State}.
43
44 allowed_methods(Req, State) ->
45 43 {[<<"OPTIONS">>, <<"GET">>, <<"POST">>, <<"PUT">>], Req, State}.
46
47 resource_exists(Req, #{jid := #jid{lserver = Server}} = State) ->
48 90 RoomIDOrJID = cowboy_req:binding(id, Req),
49 90 MUCLightDomain = muc_light_domain(Server),
50 90 case RoomIDOrJID of
51 undefined ->
52 27 Method = cowboy_req:method(Req),
53 27 case Method of
54 <<"GET">> ->
55 3 {true, Req, State};
56 _ ->
57 24 {false, Req, State}
58 end;
59 _ ->
60 63 case validate_room_id(RoomIDOrJID, Server, Req) of
61 {ok, RoomID} ->
62 62 State2 = set_room_id(RoomID, State),
63 62 does_room_exist(MUCLightDomain, Req, State2);
64 _ ->
65 1 mongoose_client_api:bad_request(Req, <<"invalid_room_id">>, State)
66 end
67 end.
68
69 set_room_id(RoomID, State = #{}) ->
70 62 State#{room_id => RoomID}.
71
72 does_room_exist(RoomS, Req, #{room_id := RoomU, jid := JID} = State) ->
73 62 HostType = mod_muc_light_utils:muc_host_to_host_type(RoomS),
74 62 case mod_muc_light_db_backend:get_info(HostType, {RoomU, RoomS}) of
75 {ok, Config, Users, Version} ->
76 58 Room = #{config => Config,
77 users => Users,
78 version => Version,
79 jid => jid:make_noprep(RoomU, RoomS, <<>>)},
80 58 CallerRole = determine_role(jid:to_lus(JID), Users),
81 58 {true, Req, State#{room => Room, role_in_room => CallerRole}};
82 _ ->
83 4 {false, Req, State}
84 end.
85
86 to_json(Req, #{room := Room} = State) ->
87 11 Config = maps:get(config, Room),
88 11 Users = maps:get(users, Room),
89 11 Resp = #{name => proplists:get_value(roomname, Config),
90 subject => proplists:get_value(subject, Config),
91 16 participants => [user_to_json(U) || U <- Users]
92 },
93 11 {jiffy:encode(Resp), Req, State};
94 to_json(Req, #{jid := #jid{luser = User, lserver = Server}} = State) ->
95 3 HostType = mod_muc_light_utils:server_host_to_host_type(Server),
96 3 Rooms = mod_muc_light_db_backend:get_user_rooms(HostType, {User, Server}, undefined),
97 3 RoomsMap = [get_room_details(RoomUS) || RoomUS <- Rooms],
98 3 {jiffy:encode(lists:flatten(RoomsMap)), Req, State}.
99
100 get_room_details({RoomID, RoomS} = RoomUS) ->
101 2 HostType = mod_muc_light_utils:muc_host_to_host_type(RoomS),
102 2 case mod_muc_light_db_backend:get_config(HostType, RoomUS) of
103 {ok, Config, _} ->
104 2 #{id => RoomID,
105 name => proplists:get_value(roomname, Config),
106 subject => proplists:get_value(subject, Config)};
107 _ ->
108
:-(
[]
109 end.
110
111
112 from_json(Req, State = #{was_replied := true}) ->
113
:-(
{true, Req, State};
114 from_json(Req, State) ->
115 28 Method = cowboy_req:method(Req),
116 28 {ok, Body, Req2} = cowboy_req:read_body(Req),
117 28 case mongoose_client_api:json_to_map(Body) of
118 {ok, #{<<"name">> := N, <<"subject">> := S} = JSONData} when is_binary(N), is_binary(S) ->
119 28 handle_request(Method, JSONData, Req2, State);
120 _ ->
121
:-(
mongoose_client_api:bad_request(Req, <<"Failed to parse parameters">>, State)
122 end.
123
124 handle_request(Method, JSONData, Req, State) ->
125 28 case handle_request_by_method(Method, JSONData, Req, State) of
126 {ok, #{jid := RoomJID}} ->
127 28 RespBody = #{<<"id">> => RoomJID#jid.luser},
128 28 RespReq = cowboy_req:set_resp_body(jiffy:encode(RespBody), Req),
129 28 {true, RespReq, State};
130 {Short, Desc} ->
131
:-(
mongoose_client_api:bad_request(Req, format_error(Short, Desc), State)
132 end.
133
134 format_error(Short, Desc) ->
135
:-(
jiffy:encode(#{module => <<"mongoose_client_api_rooms">>,
136 what => <<"Failed to create room">>,
137 reason => term_to_bin(Short),
138 description => term_to_bin(Desc)}).
139
140 term_to_bin(Term) ->
141
:-(
iolist_to_binary(io_lib:format("~p", [Term])).
142
143 handle_request_by_method(<<"POST">>, JSONData, _Req,
144 #{jid := #jid{lserver = LServer} = UserJID}) ->
145 24 #{<<"name">> := RoomName, <<"subject">> := Subject} = JSONData,
146 24 MUCServer = muc_light_domain(LServer),
147 24 mod_muc_light_api:create_room(MUCServer, UserJID, RoomName, Subject);
148 handle_request_by_method(<<"PUT">>, JSONData, Req, State) ->
149 4 assert_room_id_set(Req, State),
150 4 #{jid := #jid{lserver = LServer} = UserJID, room_id := RoomID} = State,
151 4 #{<<"name">> := RoomName, <<"subject">> := Subject} = JSONData,
152 4 MUCServer = muc_light_domain(LServer),
153 4 mod_muc_light_api:create_room(MUCServer, RoomID, UserJID, RoomName, Subject).
154
155 assert_room_id_set(_Req, #{room_id := _} = _State) ->
156 7 ok.
157
158 user_to_json({UserServer, Role}) ->
159 16 #{user => jid:to_binary(UserServer),
160 role => Role}.
161
162 muc_light_domain(Server) ->
163 181 HostType = mod_muc_light_utils:server_host_to_host_type(Server),
164 181 mod_muc_light_utils:server_host_to_muc_host(HostType, Server).
165
166 determine_role(US, Users) ->
167 58 case lists:keyfind(US, 1, Users) of
168 3 false -> none;
169 {_, Role} ->
170 55 Role
171 end.
172
173 -spec validate_room_id(RoomIDOrJID :: binary(), Server :: binary(),
174 Req :: cowboy_req:req()) ->
175 {ok, RoomID :: binary()} | error.
176 validate_room_id(RoomIDOrJID, Server, Req) ->
177 63 MUCLightDomain = muc_light_domain(Server),
178 63 case jid:from_binary(RoomIDOrJID) of
179 #jid{luser = <<>>, lserver = RoomID, lresource = <<>>} ->
180 51 {ok, RoomID};
181 #jid{luser = RoomID, lserver = MUCLightDomain, lresource = <<>>} ->
182 11 {ok, RoomID};
183 Other ->
184 1 ?LOG_WARNING(#{what => muc_invalid_room_id,
185 text => <<"REST received room_id field is invalid "
186 "or of unknown format">>,
187 server => Server, room => RoomIDOrJID, reason => Other,
188
:-(
req => Req}),
189 1 error
190 end.
Line Hits Source