Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions config/initializers/active_storage.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,16 @@
end
end

module ActiveStorageDirectUploadsControllerExtensions
extend ActiveSupport::Concern

included do
include Authentication
skip_forgery_protection if: :authenticate_by_bearer_token
end
end

Rails.application.config.to_prepare do
ActiveStorage::BaseController.include ActiveStorageControllerExtensions
ActiveStorage::DirectUploadsController.include ActiveStorageDirectUploadsControllerExtensions
end
3 changes: 2 additions & 1 deletion docs/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -178,10 +178,11 @@ curl -X POST \
"content_type": "image/png"
}
}' \
https://app.fizzy.do/rails/active_storage/direct_uploads
https://app.fizzy.do/123456/rails/active_storage/direct_uploads
```

The `checksum` is a Base64-encoded MD5 hash of the file content.
The direct upload endpoint is scoped to your account (replace `/123456` with your account slug).

__Response:__

Expand Down
72 changes: 72 additions & 0 deletions test/controllers/active_storage/direct_uploads_controller_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
require "test_helper"

class ActiveStorage::DirectUploadsControllerTest < ActionDispatch::IntegrationTest
setup do
@blob_params = {
blob: {
filename: "screenshot.png",
byte_size: 12345,
checksum: "GQ5SqLsM7ylnji0Wgd9wNC==",
content_type: "image/png"
}
}
end

test "create" do
sign_in_as :david

post rails_direct_uploads_path,
params: @blob_params,
headers: bearer_token_header(identity_access_tokens(:davids_api_token).token),
as: :json

assert_response :success
assert_includes response.parsed_body.keys, "direct_upload"
end

test "create with valid access token" do
post rails_direct_uploads_path,
params: @blob_params,
headers: bearer_token_header(identity_access_tokens(:davids_api_token).token),
as: :json

assert_response :success
assert_includes response.parsed_body.keys, "direct_upload"
end

test "create with read-only access token" do
post rails_direct_uploads_path,
params: @blob_params,
headers: bearer_token_header(identity_access_tokens(:jasons_api_token).token),
as: :json

assert_response :unauthorized
end

test "create with invalid access token" do
post rails_direct_uploads_path,
params: @blob_params,
headers: bearer_token_header("invalid_token"),
as: :json

assert_response :unauthorized
end

test "create unauthenticated" do
post rails_direct_uploads_path,
params: @blob_params.merge(authenticity_token: csrf_token),
as: :json

assert_response :redirect
end

private
def bearer_token_header(token)
{ "Authorization" => "Bearer #{token}" }
end

def csrf_token
get new_session_url
response.body[/name="csrf-token" content="([^"]+)"/, 1]
end
end