Pass the user for authentication with cookies in a cookie itself.
parent
6acd5e3a5a
commit
51675065a9
|
@ -40,7 +40,7 @@ start(_Type, StartArgs) ->
|
||||||
|
|
||||||
Dispatch = cowboy_router:compile([
|
Dispatch = cowboy_router:compile([
|
||||||
{'_', [
|
{'_', [
|
||||||
{"/api/v1/user/:username", dudeswave_user_handler, #{bucket => ?USERSBUCK,
|
{"/api/v1/user", dudeswave_user_handler, #{bucket => ?USERSBUCK,
|
||||||
cookies => ?COOKIESBUCK}},
|
cookies => ?COOKIESBUCK}},
|
||||||
{"/", dudeswave_handler, #{bucket => ?APPBUCK}}
|
{"/", dudeswave_handler, #{bucket => ?APPBUCK}}
|
||||||
]}
|
]}
|
||||||
|
|
|
@ -17,32 +17,28 @@
|
||||||
-moduledoc """
|
-moduledoc """
|
||||||
JSON API to manage users.
|
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
|
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.
|
||||||
|
|
||||||
This module accepts four methods:
|
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
|
Retrieve user's details. However, this call requires the user to have
|
||||||
a valid cookie set. Not suitable for a public page.
|
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.
|
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,
|
Remove a user forever. The data is delete immediately. However,
|
||||||
it's content is left up there. Probably a specific option will be added
|
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
|
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
|
for the simple reason that we may make the call asynchronous
|
||||||
to remove additional content in background.
|
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,
|
Register a user. The registration takes only three parameter: username,
|
||||||
password and e-mail. The e-mail is required if a confirmation message
|
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
|
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
|
JSON APIs
|
||||||
|
|
||||||
GET /api/v1/user/:username
|
GET /api/v1/user
|
||||||
|
|
||||||
```
|
```
|
||||||
{
|
{
|
||||||
|
@ -74,7 +70,7 @@ Response codes:
|
||||||
- 200 OK (Success)
|
- 200 OK (Success)
|
||||||
- 404 Not Found
|
- 404 Not Found
|
||||||
|
|
||||||
PUT /api/v1/user/:username
|
PUT /api/v1/user
|
||||||
|
|
||||||
```
|
```
|
||||||
{
|
{
|
||||||
|
@ -89,7 +85,7 @@ Response codes:
|
||||||
- 400 Bad Request
|
- 400 Bad Request
|
||||||
- 409 Conflict (User already exists)
|
- 409 Conflict (User already exists)
|
||||||
|
|
||||||
POST /api/v1/user/:username
|
POST /api/v1/user
|
||||||
|
|
||||||
```
|
```
|
||||||
{
|
{
|
||||||
|
@ -105,7 +101,7 @@ Response codes:
|
||||||
- 400 Bad Request
|
- 400 Bad Request
|
||||||
- 404 Not Found
|
- 404 Not Found
|
||||||
|
|
||||||
DELETE /api/v1/user/:username
|
DELETE /api/v1/user
|
||||||
|
|
||||||
- 202 Accepted
|
- 202 Accepted
|
||||||
- 404 Not Found
|
- 404 Not Found
|
||||||
|
@ -145,9 +141,9 @@ forbidden(Req, State) ->
|
||||||
<<"PUT">> ->
|
<<"PUT">> ->
|
||||||
{false, Req, State};
|
{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),
|
{ok, Bucket} = maps:find(cookies, State),
|
||||||
User = cowboy_req:binding(username, Req),
|
|
||||||
|
|
||||||
case dudeswave_auth:authenticate({cookie, User, Auth}, Bucket) of
|
case dudeswave_auth:authenticate({cookie, User, Auth}, Bucket) of
|
||||||
{error, service_unavailable} -> exit(service_unavailable);
|
{error, service_unavailable} -> exit(service_unavailable);
|
||||||
|
@ -177,7 +173,7 @@ content_types_accepted(Req, State) ->
|
||||||
end.
|
end.
|
||||||
|
|
||||||
resource_exists(Req, State) ->
|
resource_exists(Req, State) ->
|
||||||
User = cowboy_req:binding(username, Req),
|
#{dudename := User} = cowboy_req:match_cookies([dudename], Req),
|
||||||
{ok, Bucket} = maps:find(bucket, State),
|
{ok, Bucket} = maps:find(bucket, State),
|
||||||
|
|
||||||
case dudeswave_auth:user_details(User, Bucket) of
|
case dudeswave_auth:user_details(User, Bucket) of
|
||||||
|
@ -204,7 +200,7 @@ allow_missing_post(Req, State) -> {false, Req, State}.
|
||||||
|
|
||||||
delete_resource(Req, State) ->
|
delete_resource(Req, State) ->
|
||||||
{ok, Bucket} = maps:find(bucket, 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
|
case dudeswave_auth:delete(User, Bucket) of
|
||||||
ok -> {true, Req, State};
|
ok -> {true, Req, State};
|
||||||
|
@ -219,7 +215,7 @@ delete_completed(Req, State) -> {false, Req, State}.
|
||||||
|
|
||||||
create_user(Req, State) ->
|
create_user(Req, State) ->
|
||||||
{ok, Bucket} = maps:find(bucket, 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)),
|
#{<<"password">> := Pass, <<"email">> := Email} = json:decode(cowboy_req:body(req)),
|
||||||
|
|
||||||
|
@ -230,7 +226,7 @@ create_user(Req, State) ->
|
||||||
|
|
||||||
modify_user(Req, State) ->
|
modify_user(Req, State) ->
|
||||||
{ok, Bucket} = maps:find(bucket, 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,
|
#{<<"email">> := Email, <<"description">> := Desc,
|
||||||
<<"name">> := Name} = json:decode(cowboy_req:body(req)),
|
<<"name">> := Name} = json:decode(cowboy_req:body(req)),
|
||||||
|
@ -242,7 +238,8 @@ modify_user(Req, State) ->
|
||||||
|
|
||||||
user_details(Req, State) ->
|
user_details(Req, State) ->
|
||||||
#{details := Details} = 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}.
|
{iolist_to_binary(json:encode(Data)), Req, State}.
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue