Skip to content

Commit

Permalink
Merge pull request #379 from 2600hz/KAZOO-2563
Browse files Browse the repository at this point in the history
Kazoo 2563
  • Loading branch information
k-anderson committed Jun 20, 2014
2 parents d9930db + 8873760 commit 3d150e2
Show file tree
Hide file tree
Showing 5 changed files with 193 additions and 85 deletions.
72 changes: 72 additions & 0 deletions applications/crossbar/doc/token_auth.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*
Section: APIs
Title: Token Authentication
Language: en-US
*/

Authentication tokens are generated using one of the authentication endpoints exposed by Crossbar. See [User Authentication](./user_authentication.md) and [API Authentication](./api_authentication.md) as examples of generating authentication tokens.

Once you have an authentication token, you can access various Crossbar resource endpoints to manipulate the system or your account (provided you have the access).

Authentication tokens refresh their pvt\_modified timestamp each time they are used in an API request. Once an authentication token's pvt\_modified timestamp has passed a configurable timeout (usually one hour), it is automatically cleaned up by the system and no longer valid.

## Token Restrictions

The authentication token can be created with restrictions on what resource URIs (and HTTP methods) can be accessed by the requestor. This payload is added to the authentication payload used in any of the authentication methods provided ([User](./user_authentication.md), [API](./api_authentication.md), etc).

For example, when creating an authentication token via [API key](./api_authentication.md), include the following object to restrict the resultant authentication token to read-only:

{"data":{
"api_key":"{API_KEY}"
,"restrictions":{
"get":["#"]
}
}
}

AMQP binding tokens are used (`#` and `*`) to denote wildcards. An example with more fine-grained restrictions:

{"data":{
"api_key":"{API_KEY}"
,"restrictions":{
"get":[
"accounts/{ACCOUNT_ID}/users"
,"accounts/{ACCOUNT_ID}/users/*"
,"accounts/{ACCOUNT_ID}/users/*/*"
]
"put":[
"accounts/{ACCOUNT_ID}/users"
]
,"post":[
"accounts/{ACCOUNT_ID}/users/*"
]
,"delete":[
"accounts/{ACCOUNT_ID}/users/*"
]
}
}
}

This would restrict the authentication token to only be able to access {ACCOUNT_ID}'s users resource and perform all of the CRUD actions (as well as quickcall and channel listings for a user). We can simply this restrictions object by using `*` for the method and `#` to match any URI with `/users`:

{"data":{
"api_key":"{API_KEY}"
,"restrictions":{
"*":["accounts/{ACCOUNT_ID}/users/#"]
}
}
}

Here the `#` matches 0 or more segments after `/users`.

## API Endpoint

URL segment: `/token_auth`

## Sample cURL Requests

### Delete an authentication token

If you'd like to invalidate an authentication token programmatically (versus letting the system expire the token), you can issue a `DELETE`:

curl -v -X DELETE -H "X-Auth-Token: {AUTH_TOKEN}" http://server.com:8000/v1/token_auth
1 change: 1 addition & 0 deletions applications/crossbar/doc/user_authentication.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/*
Section: APIs
Title: User Authentication
Language: en-US
*/

# Generating an auth token from credentials
Expand Down
10 changes: 6 additions & 4 deletions applications/crossbar/src/crossbar_util.erl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
%%%-------------------------------------------------------------------
%%% @copyright (C) 2010-2013, 2600Hz
%%% @copyright (C) 2010-2014, 2600Hz
%%% @doc
%%%
%%% @end
Expand Down Expand Up @@ -578,11 +578,13 @@ create_auth_token(Context, Method) ->
,{<<"api_key">>, wh_json:get_value(<<"api_key">>, Data)}
,{<<"restrictions">>, wh_json:get_value(<<"restrictions">>, Data)}
,{<<"modified">>, Timestamp}
,{<<"method">>, wh_util:to_binary(Method)}]
),
,{<<"method">>, wh_util:to_binary(Method)}
]),
JObjToken = wh_doc:update_pvt_parameters(wh_json:from_list(Token)
,wh_util:format_account_id(AccountId, 'encoded')
,Token),
,[{'now', Timestamp}
,{'account_id', AccountId}
]),
case couch_mgr:save_doc(?TOKEN_DB, JObjToken) of
{'ok', Doc} ->
AuthToken = wh_json:get_value(<<"_id">>, Doc),
Expand Down
9 changes: 4 additions & 5 deletions applications/crossbar/src/modules/cb_faxboxes.erl
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ put(Context) ->
-spec post(cb_context:context(), path_token()) -> cb_context:context().
post(Context, _Id) ->
Ctx = maybe_register_cloud_printer(Context),
Ctx2 = crossbar_doc:save(Ctx),
Ctx2 = crossbar_doc:save(Ctx),
_ = crossbar_doc:ensure_saved(
cb_context:set_doc(
cb_context:set_account_db(Ctx2, ?WH_FAXES),
Expand All @@ -175,7 +175,7 @@ post(Context, _Id) ->
delete(Context, Id) ->
Ctx2 = crossbar_doc:delete(Context),
_ = crossbar_doc:delete(
read(Id,
read(Id,
cb_context:set_account_db(Context, ?WH_FAXES))),
Ctx2.

Expand Down Expand Up @@ -213,14 +213,13 @@ leak_private_fields(JObj) ->
-spec remove_private_fields(cb_context:context()) -> cb_context:context().
remove_private_fields(Context) ->
JObj = cb_context:req_data(Context),
JObj1 = lists:foldl(fun(<<"pvt_", K1/binary>> = K, Acc) ->
JObj1 = lists:foldl(fun(<<"pvt_", K1/binary>>, Acc) ->
case wh_json:get_value(K1, Acc) of
'undefined' -> Acc;
Value -> wh_json:delete_key(K1, Acc)
_Value -> wh_json:delete_key(K1, Acc)
end
end, JObj, ?LEAKED_FIELDS),
cb_context:set_req_data(Context, JObj1).


%%--------------------------------------------------------------------
%% @private
Expand Down
Loading

0 comments on commit 3d150e2

Please sign in to comment.