Pass the user for authentication with cookies in a cookie itself.

main
absc 2024-08-09 20:37:47 +00:00
parent 6acd5e3a5a
commit 51675065a9
2 changed files with 21 additions and 24 deletions

View File

@ -40,7 +40,7 @@ start(_Type, StartArgs) ->
Dispatch = cowboy_router:compile([
{'_', [
{"/api/v1/user/:username", dudeswave_user_handler, #{bucket => ?USERSBUCK,
{"/api/v1/user", dudeswave_user_handler, #{bucket => ?USERSBUCK,
cookies => ?COOKIESBUCK}},
{"/", dudeswave_handler, #{bucket => ?APPBUCK}}
]}

View File

@ -17,32 +17,28 @@
-moduledoc """
JSON API to manage users.
The username should be passed as the last token in the request, like:
The username is passed in a cookie. The handler recover it from the
session. Cookies are:
```
/api/v1/user/foo
dudename # the actual username
dudeauth # the authentication cookie
```
Where `foo` is the actual username.
The user parameter must be called `username` as this module expects it
in order to work properly. All the requests must be done with a valid
session cookie in order to work.
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`
is returned.
This module accepts four methods:
- GET /api/v1/user/:username
- GET /api/v1/user
Retrieve user's details. However, this call requires the user to have
a valid cookie set. Not suitable for a public page.
- POST /api/v1/user/:username
- POST /api/v1/user
Update user's details, like their name, description and whatnot.
- DELETE /api/v1/user/:username
- DELETE /api/v1/user
Remove a user forever. The data is delete immediately. However,
it's content is left up there. Probably a specific option will be added
later. This request does not have a body. The call deletes the user
@ -50,7 +46,7 @@ This module accepts four methods:
for the simple reason that we may make the call asynchronous
to remove additional content in background.
- PUT /api/v1/user/:username
- PUT /api/v1/user
Register a user. The registration takes only three parameter: username,
password and e-mail. The e-mail is required if a confirmation message
is to be sent. The plan is to have a separate process handle this, so the
@ -58,7 +54,7 @@ This module accepts four methods:
JSON APIs
GET /api/v1/user/:username
GET /api/v1/user
```
{
@ -74,7 +70,7 @@ Response codes:
- 200 OK (Success)
- 404 Not Found
PUT /api/v1/user/:username
PUT /api/v1/user
```
{
@ -89,7 +85,7 @@ Response codes:
- 400 Bad Request
- 409 Conflict (User already exists)
POST /api/v1/user/:username
POST /api/v1/user
```
{
@ -105,7 +101,7 @@ Response codes:
- 400 Bad Request
- 404 Not Found
DELETE /api/v1/user/:username
DELETE /api/v1/user
- 202 Accepted
- 404 Not Found
@ -145,9 +141,9 @@ forbidden(Req, State) ->
<<"PUT">> ->
{false, Req, State};
_ ->
#{dudeauth := Auth} = cowboy_req:match_cookies([dudeauth], Req),
#{dudeauth := Auth, dudename := User} = cowboy_req:match_cookies([dudeauth,
dudename], Req),
{ok, Bucket} = maps:find(cookies, State),
User = cowboy_req:binding(username, Req),
case dudeswave_auth:authenticate({cookie, User, Auth}, Bucket) of
{error, service_unavailable} -> exit(service_unavailable);
@ -177,7 +173,7 @@ content_types_accepted(Req, State) ->
end.
resource_exists(Req, State) ->
User = cowboy_req:binding(username, Req),
#{dudename := User} = cowboy_req:match_cookies([dudename], Req),
{ok, Bucket} = maps:find(bucket, State),
case dudeswave_auth:user_details(User, Bucket) of
@ -204,7 +200,7 @@ allow_missing_post(Req, State) -> {false, Req, State}.
delete_resource(Req, State) ->
{ok, Bucket} = maps:find(bucket, State),
User = cowboy_req:binding(username, Req),
#{dudename := User} = cowboy_req:match_cookies([dudename], Req),
case dudeswave_auth:delete(User, Bucket) of
ok -> {true, Req, State};
@ -219,7 +215,7 @@ delete_completed(Req, State) -> {false, Req, State}.
create_user(Req, State) ->
{ok, Bucket} = maps:find(bucket, State),
User = cowboy_req:binding(username, Req),
#{dudename := User} = cowboy_req:match_cookies([dudename], Req),
#{<<"password">> := Pass, <<"email">> := Email} = json:decode(cowboy_req:body(req)),
@ -230,7 +226,7 @@ create_user(Req, State) ->
modify_user(Req, State) ->
{ok, Bucket} = maps:find(bucket, State),
User = cowboy_req:binding(username, Req),
#{dudename := User} = cowboy_req:match_cookies([dudename], Req),
#{<<"email">> := Email, <<"description">> := Desc,
<<"name">> := Name} = json:decode(cowboy_req:body(req)),
@ -242,7 +238,8 @@ modify_user(Req, State) ->
user_details(Req, State) ->
#{details := Details} = State,
Data = Details#{user => cowboy_req:binding(username, Req)},
#{dudename := User} = cowboy_req:match_cookies([dudename], Req),
Data = Details#{user => User},
{iolist_to_binary(json:encode(Data)), Req, State}.