Add JSON response format to access token creation (#2662)
* Add JSON response format to access token creation Allows programmatic clients (e.g., CLI) to create access tokens via the API by returning the token, description, and permission as JSON instead of redirecting to the HTML show page. * Add JSON response format to access token creation Allows programmatic clients (e.g., CLI) to create access tokens via the API by returning the token, description, and permission as JSON instead of redirecting to the HTML show page. * Style --------- Co-authored-by: David Heinemeier Hansson <david@hey.com>
This commit is contained in:
@@ -15,11 +15,20 @@ class My::AccessTokensController < ApplicationController
|
||||
|
||||
def create
|
||||
access_token = my_access_tokens.create!(access_token_params)
|
||||
expiring_id = verifier.generate access_token.id, expires_in: 10.seconds
|
||||
|
||||
respond_to do |format|
|
||||
format.html do
|
||||
expiring_id = verifier.generate access_token.id, expires_in: 10.seconds
|
||||
redirect_to my_access_token_path(expiring_id)
|
||||
end
|
||||
|
||||
format.json do
|
||||
render status: :created, json: \
|
||||
{ token: access_token.token, description: access_token.description, permission: access_token.permission }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
my_access_tokens.find(params[:id]).destroy!
|
||||
redirect_to my_access_tokens_path
|
||||
|
||||
+42
@@ -134,6 +134,48 @@ __Response:__
|
||||
|
||||
Returns `204 No Content` on success.
|
||||
|
||||
#### Create an access token via the API
|
||||
|
||||
You can programmatically create a personal access token using either a session cookie or an existing Bearer token:
|
||||
|
||||
```bash
|
||||
curl -X POST \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Accept: application/json" \
|
||||
-H "Cookie: session_token=eyJfcmFpbHMi..." \
|
||||
-d '{"access_token": {"description": "Fizzy CLI", "permission": "write"}}' \
|
||||
https://app.fizzy.do/1234567/my/access_tokens
|
||||
```
|
||||
|
||||
Or with a Bearer token (must have `write` permission):
|
||||
|
||||
```bash
|
||||
curl -X POST \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Accept: application/json" \
|
||||
-H "Authorization: Bearer put-your-access-token-here" \
|
||||
-d '{"access_token": {"description": "Fizzy CLI", "permission": "write"}}' \
|
||||
https://app.fizzy.do/1234567/my/access_tokens
|
||||
```
|
||||
|
||||
The `permission` field accepts `read` or `write`.
|
||||
|
||||
__Response:__
|
||||
|
||||
```
|
||||
HTTP/1.1 201 Created
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"token": "4f9Q6d2wXr8Kp1Ls0Vz3BnTa",
|
||||
"description": "Fizzy CLI",
|
||||
"permission": "write"
|
||||
}
|
||||
```
|
||||
|
||||
Store the `token` value securely — it won't be retrievable again. Use it as a Bearer token for subsequent API requests.
|
||||
|
||||
## Caching
|
||||
|
||||
Most endpoints return [ETag](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/ETag) and [Cache-Control](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Cache-Control) headers. You can use these to avoid re-downloading unchanged data.
|
||||
|
||||
@@ -19,6 +19,41 @@ class My::AccessTokensControllerTest < ActionDispatch::IntegrationTest
|
||||
end
|
||||
end
|
||||
|
||||
test "create new token via JSON with session" do
|
||||
assert_difference -> { identities(:kevin).access_tokens.count }, +1 do
|
||||
post my_access_tokens_path, params: { access_token: { description: "Fizzy CLI", permission: "write" } }, as: :json
|
||||
end
|
||||
assert_response :created
|
||||
body = @response.parsed_body
|
||||
assert body["token"].present?
|
||||
assert_equal "Fizzy CLI", body["description"]
|
||||
assert_equal "write", body["permission"]
|
||||
end
|
||||
|
||||
test "create new token via JSON with bearer token" do
|
||||
sign_out
|
||||
bearer_token = { "HTTP_AUTHORIZATION" => "Bearer #{identity_access_tokens(:davids_api_token).token}" }
|
||||
|
||||
assert_difference -> { identities(:david).access_tokens.count }, +1 do
|
||||
post my_access_tokens_path, params: { access_token: { description: "Fizzy CLI", permission: "read" } }, env: bearer_token, as: :json
|
||||
end
|
||||
assert_response :created
|
||||
body = @response.parsed_body
|
||||
assert body["token"].present?
|
||||
assert_equal "Fizzy CLI", body["description"]
|
||||
assert_equal "read", body["permission"]
|
||||
end
|
||||
|
||||
test "cannot create new token via JSON with read-only bearer token" do
|
||||
sign_out
|
||||
bearer_token = { "HTTP_AUTHORIZATION" => "Bearer #{identity_access_tokens(:jasons_api_token).token}" }
|
||||
|
||||
assert_no_difference -> { identities(:jason).access_tokens.count } do
|
||||
post my_access_tokens_path, params: { access_token: { description: "Fizzy CLI", permission: "read" } }, env: bearer_token, as: :json
|
||||
end
|
||||
assert_response :unauthorized
|
||||
end
|
||||
|
||||
test "accessing new token after reveal window redirects to index" do
|
||||
assert_changes -> { identities(:kevin).access_tokens.count }, +1 do
|
||||
post my_access_tokens_path, params: { access_token: { description: "GitHub", permission: "read" } }
|
||||
|
||||
Reference in New Issue
Block a user