./ct_report/coverage/mongoose_admin_api_domain.COVER.html

1 -module(mongoose_admin_api_domain).
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_provided/2,
10 content_types_accepted/2,
11 allowed_methods/2,
12 to_json/2,
13 from_json/2,
14 delete_resource/2,
15 delete_completed/2]).
16
17 -ignore_xref([to_json/2, from_json/2]).
18
19 -import(mongoose_admin_api, [parse_body/1, throw_error/2, resource_created/4]).
20
21 -type req() :: cowboy_req:req().
22 -type state() :: mongoose_admin_api:state().
23
24 -spec routes(state()) -> mongoose_http_handler:routes().
25 routes(State) ->
26 4 [{"/domains/:domain", ?MODULE, State}].
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_provided(req(), state()) ->
37 {[{{binary(), binary(), '*'}, atom()}], req(), state()}.
38 content_types_provided(Req, State) ->
39
:-(
{[
40 {{<<"application">>, <<"json">>, '*'}, to_json}
41 ], Req, State}.
42
43 -spec content_types_accepted(req(), state()) ->
44 {[{{binary(), binary(), '*'}, atom()}], req(), state()}.
45 content_types_accepted(Req, State) ->
46
:-(
{[
47 {{<<"application">>, <<"json">>, '*'}, from_json}
48 ], Req, State}.
49
50 -spec allowed_methods(req(), state()) -> {[binary()], req(), state()}.
51 allowed_methods(Req, State) ->
52
:-(
{[<<"OPTIONS">>, <<"GET">>, <<"PATCH">>, <<"PUT">>, <<"DELETE">>], Req, State}.
53
54 %% @doc Called for a method of type "GET"
55 -spec to_json(req(), state()) -> {iodata() | stop, req(), state()}.
56 to_json(Req, State) ->
57
:-(
try_handle_request(Req, State, fun handle_get/2).
58
59 %% @doc Called for a method of type "PUT" or "PATCH"
60 -spec from_json(req(), state()) -> {true | stop, req(), state()}.
61 from_json(Req, State) ->
62
:-(
F = case cowboy_req:method(Req) of
63
:-(
<<"PUT">> -> fun handle_put/2;
64
:-(
<<"PATCH">> -> fun handle_patch/2
65 end,
66
:-(
try_handle_request(Req, State, F).
67
68 %% @doc Called for a method of type "DELETE"
69 -spec delete_resource(req(), state()) -> {true | stop, req(), state()}.
70 delete_resource(Req, State) ->
71
:-(
try_handle_request(Req, State, fun handle_delete/2).
72
73 -spec delete_completed(req(), state()) -> {boolean(), req(), state()}.
74 delete_completed(Req, #{deletion := in_process} = State) ->
75
:-(
{false, Req, State};
76 delete_completed(Req, State) ->
77
:-(
{true, Req, State}.
78
79 %% Internal functions
80
81 try_handle_request(Req, State, Handler) ->
82
:-(
F = fun(ReqIn, StateIn) ->
83
:-(
case service_domain_db:enabled() of
84
:-(
true -> Handler(ReqIn, StateIn);
85
:-(
false -> throw_error(denied, <<"Dynamic domains service is disabled">>)
86 end
87 end,
88
:-(
mongoose_admin_api:try_handle_request(Req, State, F).
89
90 handle_get(Req, State) ->
91
:-(
Bindings = cowboy_req:bindings(Req),
92
:-(
Domain = get_domain(Bindings),
93
:-(
case mongoose_domain_api:get_domain_details(Domain) of
94 {ok, Props} ->
95
:-(
{jiffy:encode(maps:with([host_type, status], Props)), Req, State};
96 {not_found, Msg} ->
97
:-(
throw_error(not_found, Msg);
98 {_, Msg} ->
99
:-(
throw_error(denied, Msg)
100 end.
101
102 handle_put(Req, State) ->
103
:-(
Bindings = cowboy_req:bindings(Req),
104
:-(
Domain = get_domain(Bindings),
105
:-(
Args = parse_body(Req),
106
:-(
HostType = get_host_type(Args),
107
:-(
case mongoose_domain_api:insert_domain(Domain, HostType) of
108 {ok, _} ->
109
:-(
{true, Req, State};
110 {duplicate, Msg} ->
111
:-(
throw_error(duplicate, Msg);
112 {_, Msg} ->
113
:-(
throw_error(denied, Msg)
114 end.
115
116 handle_patch(Req, State) ->
117
:-(
Bindings = cowboy_req:bindings(Req),
118
:-(
Domain = get_domain(Bindings),
119
:-(
Args = parse_body(Req),
120
:-(
Result = case get_enabled(Args) of
121 true ->
122
:-(
mongoose_domain_api:enable_domain(Domain);
123 false ->
124
:-(
mongoose_domain_api:disable_domain(Domain)
125 end,
126
:-(
case Result of
127 {ok, _} ->
128
:-(
{true, Req, State};
129 {not_found, Msg} ->
130
:-(
throw_error(not_found, Msg);
131 {_, Msg} ->
132
:-(
throw_error(denied, Msg)
133 end.
134
135 handle_delete(Req, State) ->
136
:-(
Bindings = cowboy_req:bindings(Req),
137
:-(
Domain = get_domain(Bindings),
138
:-(
Args = parse_body(Req),
139
:-(
handle_delete(Req, State, Domain, Args).
140
141 handle_delete(Req, State, Domain, #{host_type := HostType, request := true}) ->
142
:-(
async_delete(Req, State, Domain, HostType);
143 handle_delete(Req, State, Domain, #{host_type := HostType}) ->
144
:-(
sync_delete(Req, State, Domain, HostType);
145 handle_delete(_Req, _State, _Domain, #{}) ->
146
:-(
throw_error(bad_request, <<"'host_type' field is missing">>).
147
148 async_delete(Req, State, Domain, HostType) ->
149
:-(
case mongoose_domain_api:request_delete_domain(Domain, HostType) of
150 {ok, _} ->
151
:-(
{true, Req, State#{deletion => in_process}};
152 {not_found, Msg} ->
153
:-(
throw_error(not_found, Msg);
154 {_Reason, Msg} ->
155
:-(
throw_error(denied, Msg)
156 end.
157
158 sync_delete(Req, State, Domain, HostType) ->
159
:-(
case mongoose_domain_api:delete_domain(Domain, HostType) of
160 {ok, _} ->
161
:-(
{true, Req, State};
162 {not_found, Msg} ->
163
:-(
throw_error(not_found, Msg);
164 {_Reason, Msg} ->
165
:-(
throw_error(denied, Msg)
166 end.
167
168 get_domain(#{domain := Domain}) ->
169
:-(
case jid:nameprep(Domain) of
170
:-(
error -> throw_error(bad_request, <<"Invalid domain name">>);
171
:-(
PrepDomain -> PrepDomain
172 end.
173
174
:-(
get_host_type(#{host_type := HostType}) -> HostType;
175
:-(
get_host_type(#{}) -> throw_error(bad_request, <<"'host_type' field is missing">>).
176
177
:-(
get_enabled(#{enabled := Enabled}) -> Enabled;
178
:-(
get_enabled(#{}) -> throw_error(bad_request, <<"'enabled' field is missing">>).
Line Hits Source