Compare commits

...

5 Commits

Author SHA1 Message Date
absc 45b5bc3d2d Corrected documentation string. 2024-08-15 22:44:45 +00:00
absc 18a430614f Use proplists instead of lists. 2024-08-15 22:39:22 +00:00
absc e95e91b645 The defines file is not needed here. 2024-08-15 22:15:57 +00:00
absc ae07951cd2 Add the authentication handler to the routes. 2024-08-15 22:11:19 +00:00
absc 1ca3e1f4ef No need to mention the cookies. 2024-08-15 22:08:46 +00:00
3 changed files with 13 additions and 20 deletions

View File

@ -18,8 +18,6 @@
-export([bootstrap/3, start/2, stop/1]). -export([bootstrap/3, start/2, stop/1]).
-include_lib("dudeswave/include/defines.hrl").
start(_Type, StartArgs) -> start(_Type, StartArgs) ->
crypto:rand_seed(), crypto:rand_seed(),
@ -38,6 +36,7 @@ start(_Type, StartArgs) ->
Dispatch = cowboy_router:compile([ Dispatch = cowboy_router:compile([
{'_', [ {'_', [
{"/api/v1/auth", dudeswave_auth_handler, #{}},
{"/api/v1/user", dudeswave_user_handler, #{}}, {"/api/v1/user", dudeswave_user_handler, #{}},
{"/", dudeswave_handler, #{}} {"/", dudeswave_handler, #{}}
]} ]}

View File

@ -17,8 +17,8 @@
-moduledoc """ -moduledoc """
Dudes users management module. Dudes users management module.
Here lives all the functions needed to create, update and delete users Here lives all the functions for the APIs needed to create, update and delete
from the dudeswave database. users from the dudeswave database.
""". """.
-include_lib("dudeswave/include/defines.hrl"). -include_lib("dudeswave/include/defines.hrl").
@ -59,7 +59,7 @@ authenticate(User, {cookie, Cookie}) ->
{ok, [R]} -> {ok, [R]} ->
CurTime = calendar:now_to_universal_time(erlang:timestamp()), CurTime = calendar:now_to_universal_time(erlang:timestamp()),
CookieTime = R#object.value, CookieTime = R#object.value,
CookieUser = lists:keyfind(user, 1, R#object.metadata), {user, CookieUser} = proplists:lookup(user, R#object.metadata),
if if
CookieTime >= CurTime -> CookieTime >= CurTime ->
@ -83,11 +83,14 @@ authenticate(User, {password, Password}) ->
erlang:system_time(seconds) + ?DEFVALIDITY * 86400 erlang:system_time(seconds) + ?DEFVALIDITY * 86400
end, end,
{ok, Hash} = lists:keyfind(hash, 1, R#object.metadata), {hash, Hash} = proplists:lookup(hash, R#object.metadata),
{ok, Salt} = lists:keyfind(salt, 1, R#object.metadata), {salt, Salt} = proplists:lookup(salt, R#object.metadata),
{approved, Appr} = proplists:lookup(approved, R#object.metadata),
Auth = crypto:hash(sha256, <<Password/binary, Salt/binary>>), Auth = crypto:hash(sha256, <<Password/binary, Salt/binary>>),
if if
Appr =/= true -> false;
Auth =:= Hash -> Auth =:= Hash ->
Cookie = base64:encode(rand:bytes(64)), Cookie = base64:encode(rand:bytes(64)),
case storage:write(?COOKIESBUCK, <<Cookie/binary>>, case storage:write(?COOKIESBUCK, <<Cookie/binary>>,
@ -123,7 +126,7 @@ Invalidate and delete `Cookie` associated with `User` from the system.
logout(User, Cookie) -> logout(User, Cookie) ->
case storage:read(?COOKIESBUCK, Cookie) of case storage:read(?COOKIESBUCK, Cookie) of
{ok, [R]} -> {ok, [R]} ->
{user, User} = lists:keyfind(user, 1, R#object.metadata), {user, User} = proplists:lookup(user, R#object.metadata),
storage:delete(?COOKIESBUCK, Cookie); storage:delete(?COOKIESBUCK, Cookie);
{ok, []} -> {ok, []} ->
{error, not_found}; {error, not_found};
@ -171,8 +174,7 @@ Spec:
The `User` is created, and stored in the application's users bucket The `User` is created, and stored in the application's users bucket
`Password` is salted and hashed with SHA256 before being stored. `Password` is salted and hashed with SHA256 before being stored.
The new user is saved with a metadata `status` of `waiting_confirmation`, The new user is saved with a metadata `approved` of `false`,
based on the application settings, the confirmation method may vary.
""". """.
-spec new(User, Password, Email) -> ok | {error, Reason} when -spec new(User, Password, Email) -> ok | {error, Reason} when
User :: binary(), User :: binary(),
@ -185,7 +187,7 @@ new(User, Password, Email) ->
Hash = crypto:hash(sha256, <<Password/binary, Salt/binary>>), Hash = crypto:hash(sha256, <<Password/binary, Salt/binary>>),
Data = #{<<"email">> => Email}, Data = #{<<"email">> => Email},
Metadata = [{salt, Salt}, {hash, Hash}, {status, waiting_confirmation}], Metadata = [{salt, Salt}, {hash, Hash}, {approved, false}],
storage:write(?USERSBUCK, User, Data, Metadata). storage:write(?USERSBUCK, User, Data, Metadata).
@ -295,7 +297,7 @@ invalidate_cookies(Req) ->
Req1. Req1.
-doc """ -doc """
Set the authentication cookies for the provided clien request Set the authentication cookies for the provided client request
Spec: Spec:

View File

@ -17,14 +17,6 @@
-moduledoc """ -moduledoc """
JSON API to manage users. JSON API to manage users.
The username is passed in a cookie. The handler recover it from the
session. Cookies are:
```
dudename: the actual username
dudeauth: the authentication cookie
```
If the session is not valid, all the requests will return `403 Forbidden` to If the session is not valid, all the requests will return `403 Forbidden` to
the client. In case a technical problem occurs, `500 Internal Server Error` the client. In case a technical problem occurs, `500 Internal Server Error`
is returned. is returned.