./ct_report/coverage/mongoose_admin_api_users.COVER.html

1 -module(mongoose_admin_api_users).
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
16 -ignore_xref([to_json/2, from_json/2]).
17
18 -import(mongoose_admin_api, [parse_body/1, try_handle_request/3, throw_error/2, resource_created/4]).
19
20 -type req() :: cowboy_req:req().
21 -type state() :: mongoose_admin_api:state().
22
23 -spec routes(state()) -> mongoose_http_handler:routes().
24 routes(State) ->
25 110 [{"/users/:domain/[:username]", ?MODULE, State}].
26
27 -spec init(req(), state()) -> {cowboy_rest, req(), state()}.
28 init(Req, State) ->
29 25 mongoose_admin_api:init(Req, State).
30
31 -spec is_authorized(req(), state()) -> {true | {false, iodata()}, req(), state()}.
32 is_authorized(Req, State) ->
33 25 mongoose_admin_api:is_authorized(Req, State).
34
35 -spec content_types_provided(req(), state()) ->
36 {[{{binary(), binary(), '*'}, atom()}], req(), state()}.
37 content_types_provided(Req, State) ->
38 23 {[
39 {{<<"application">>, <<"json">>, '*'}, to_json}
40 ], Req, State}.
41
42 -spec content_types_accepted(req(), state()) ->
43 {[{{binary(), binary(), '*'}, atom()}], req(), state()}.
44 content_types_accepted(Req, State) ->
45 15 {[
46 {{<<"application">>, <<"json">>, '*'}, from_json}
47 ], Req, State}.
48
49 -spec allowed_methods(req(), state()) -> {[binary()], req(), state()}.
50 allowed_methods(Req, State) ->
51 25 {[<<"OPTIONS">>, <<"GET">>, <<"POST">>, <<"PUT">>, <<"DELETE">>], Req, State}.
52
53 %% @doc Called for a method of type "GET"
54 -spec to_json(req(), state()) -> {iodata() | stop, req(), state()}.
55 to_json(Req, State) ->
56 5 try_handle_request(Req, State, fun handle_get/2).
57
58 %% @doc Called for a method of type "POST" or "PUT"
59 -spec from_json(req(), state()) -> {true | stop, req(), state()}.
60 from_json(Req, State) ->
61 15 F = case cowboy_req:method(Req) of
62 8 <<"POST">> -> fun handle_post/2;
63 7 <<"PUT">> -> fun handle_put/2
64 end,
65 15 try_handle_request(Req, State, F).
66
67 %% @doc Called for a method of type "DELETE"
68 -spec delete_resource(req(), state()) -> {true | stop, req(), state()}.
69 delete_resource(Req, State) ->
70 3 try_handle_request(Req, State, fun handle_delete/2).
71
72 %% Internal functions
73
74 handle_get(Req, State) ->
75 5 #{domain := Domain} = cowboy_req:bindings(Req),
76 5 Users = mongoose_account_api:list_users(Domain),
77 5 {_, UsersList} = Users,
78 5 {jiffy:encode(UsersList), Req, State}.
79
80 handle_post(Req, State) ->
81 8 #{domain := Domain} = cowboy_req:bindings(Req),
82 8 Args = parse_body(Req),
83 7 UserName = get_user_name(Args),
84 6 Password = get_password(Args),
85 5 case mongoose_account_api:register_user(UserName, Domain, Password) of
86 {exists, Reason} ->
87 1 throw_error(denied, Reason);
88 {invalid_jid, Reason} ->
89 1 throw_error(bad_request, Reason);
90 {cannot_register, Reason} ->
91 2 throw_error(denied, Reason);
92 {ok, Result} ->
93 1 Path = [cowboy_req:uri(Req), "/", UserName],
94 1 resource_created(Req, State, Path, Result)
95 end.
96
97 handle_put(Req, State) ->
98 7 #{domain := Domain} = Bindings = cowboy_req:bindings(Req),
99 7 UserName = get_user_name(Bindings),
100 6 Args = parse_body(Req),
101 6 Password = get_new_password(Args),
102 5 case mongoose_account_api:change_password(UserName, Domain, Password) of
103 {empty_password, Reason} ->
104 1 throw_error(bad_request, Reason);
105 {invalid_jid, Reason} ->
106 1 throw_error(bad_request, Reason);
107 {not_allowed, Reason} ->
108 1 throw_error(denied, Reason);
109 {ok, _} ->
110 2 {true, Req, State}
111 end.
112
113 handle_delete(Req, State) ->
114 3 #{domain := Domain} = Bindings = cowboy_req:bindings(Req),
115 3 UserName = get_user_name(Bindings),
116 3 case mongoose_account_api:unregister_user(UserName, Domain) of
117 {invalid_jid, Reason} ->
118 1 throw_error(bad_request, Reason);
119 {not_allowed, Reason} ->
120 1 throw_error(denied, Reason);
121 {ok, _} ->
122 1 {true, Req, State}
123 end.
124
125 15 get_user_name(#{username := UserName}) -> UserName;
126 2 get_user_name(#{}) -> throw_error(bad_request, <<"Missing user name">>).
127
128 5 get_password(#{password := Password}) -> Password;
129 1 get_password(#{}) -> throw_error(bad_request, <<"Missing password">>).
130
131 5 get_new_password(#{newpass := Password}) -> Password;
132 1 get_new_password(#{}) -> throw_error(bad_request, <<"Missing new password">>).
Line Hits Source