/__w/shurbej/shurbej/_build/test/cover/ct/shurbej_http_auth.html

1 -module(shurbej_http_auth).
2 -include_lib("shurbej_store/include/shurbej_records.hrl").
3
4 -export([init/2]).
5
6 %% POST /auth/login — JSON-based login for the web UI.
7 %% Accepts: {"username": "...", "password": "..."}
8 %% Returns: {"apiKey": "...", "userID": N, "username": "..."}
9 init(Req0, State) ->
10 22 case cowboy_req:method(Req0) of
11 21 <<"POST">> -> handle_login(Req0, State);
12 _ ->
13 1 Req = shurbej_http_common:error_response(405, <<"Method not allowed">>, Req0),
14 1 {ok, Req, State}
15 end.
16
17 handle_login(Req0, State) ->
18 21 case shurbej_http_common:read_json_body(Req0) of
19 {ok, #{<<"username">> := Username, <<"password">> := Password}, Req1} ->
20 19 case shurbej_session:check_login_rate(Username) of
21 {error, rate_limited} ->
22 7 Req = shurbej_http_common:error_response(429,
23 <<"Too many login attempts. Please wait a few minutes.">>, Req1),
24 7 {ok, Req, State};
25 ok ->
26 12 case shurbej_db:authenticate_user(Username, Password) of
27 {ok, UserId} ->
28 1 shurbej_session:record_login_success(Username),
29 1 ApiKey = generate_api_key(),
30 1 shurbej_db:create_key(ApiKey, UserId,
31 shurbej_http_common:normalize_perms(undefined)),
32 1 Body = #{
33 <<"apiKey">> => ApiKey,
34 <<"userID">> => UserId,
35 <<"username">> => Username
36 },
37 1 Req = shurbej_http_common:json_response(200, Body, Req1),
38 1 {ok, Req, State};
39 {error, invalid} ->
40 11 Req = shurbej_http_common:error_response(401,
41 <<"Invalid username or password">>, Req1),
42 11 {ok, Req, State}
43 end
44 end;
45 {ok, _, Req1} ->
46 1 Req = shurbej_http_common:error_response(400,
47 <<"Missing username or password">>, Req1),
48 1 {ok, Req, State};
49 {error, _Reason, Req1} ->
50 1 Req = shurbej_http_common:error_response(400,
51 <<"Invalid JSON">>, Req1),
52 1 {ok, Req, State}
53 end.
54
55 generate_api_key() ->
56 1 binary:encode_hex(crypto:strong_rand_bytes(32), lowercase).
Line Hits Source