Only allow writing when the access token has permission

This commit is contained in:
David Heinemeier Hansson
2025-12-02 15:27:21 +01:00
committed by Stanko K.R.
parent d36be764e2
commit 0ce3a85778
3 changed files with 17 additions and 2 deletions
+4 -2
View File
@@ -59,8 +59,10 @@ module Authentication
authorization_scheme, bearer_token = request.authorization.to_s.split(" ", 2)
if authorization_scheme == "Bearer" && bearer_token.present?
if identity = Identity.find_by_access_token(bearer_token)
Current.identity = identity
access_token = Identity::AccessToken.find_by(token: bearer_token)
if access_token && access_token.allows?(request.method)
Current.identity = access_token.identity
else
head :unauthorized
end
+4
View File
@@ -3,4 +3,8 @@ class Identity::AccessToken < ApplicationRecord
has_secure_token
enum :permission, %w[ read write ].index_by(&:itself), default: :read
def allows?(method)
method.in?(%w[ GET HEAD ]) || write?
end
end
+9
View File
@@ -3,6 +3,7 @@ require "test_helper"
class ApiTest < ActionDispatch::IntegrationTest
setup do
@davids_bearer_token = bearer_token_env(identity_access_tokens(:davids_api_token).token)
@jasons_bearer_token = bearer_token_env(identity_access_tokens(:jasons_api_token).token)
end
test "authenticate with valid access token" do
@@ -15,6 +16,14 @@ class ApiTest < ActionDispatch::IntegrationTest
assert_response :unauthorized
end
test "changing data requires a write-endowed access token" do
post boards_path(format: :json), params: { board: { name: "My new board" } }, env: @jasons_bearer_token
assert_response :unauthorized
post boards_path(format: :json), params: { board: { name: "My new board" } }, env: @davids_bearer_token
assert_response :redirect
end
test "boards" do
get boards_path(format: :json), env: @davids_bearer_token
assert_equal users(:david).boards.count, @response.parsed_body.count