refactor: align conversation direct uploads with api token auth chain

This commit is contained in:
Shivam Mishra
2026-05-27 17:18:33 +05:30
parent ae676077ed
commit 2f607f67c4
2 changed files with 45 additions and 30 deletions
@@ -1,6 +1,8 @@
class Api::V1::Accounts::Conversations::DirectUploadsController < ActiveStorage::DirectUploadsController
include EnsureCurrentAccountHelper
include AccessTokenAuthHelper
include RequestExceptionHandler
before_action :authenticate_access_token!
before_action :prevent_read_only_access_token!
before_action :current_account
before_action :conversation
@@ -7,43 +7,56 @@ RSpec.describe '/api/v1/accounts/:account_id/conversations/:conversation_id/dire
let(:contact) { create(:contact, account: account, email: nil) }
let(:contact_inbox) { create(:contact_inbox, contact: contact, inbox: web_widget.inbox) }
let(:conversation) { create(:conversation, contact: contact, account: account, inbox: web_widget.inbox, contact_inbox: contact_inbox) }
let(:blob_params) do
{
blob: {
filename: 'avatar.png',
byte_size: '1234',
checksum: 'dsjbsdhbfif3874823mnsdbf',
content_type: 'image/png'
}
}
end
def upload(headers: {})
post api_v1_account_conversation_direct_uploads_path(account_id: account.id, conversation_id: conversation.display_id),
params: blob_params,
headers: headers,
as: :json
end
describe 'POST /api/v1/accounts/:account_id/conversations/:conversation_id/direct_uploads' do
context 'when post request is made' do
it 'creates attachment message in conversation' do
contact
post api_v1_account_conversation_direct_uploads_path(account_id: account.id, conversation_id: conversation.display_id),
params: {
blob: {
filename: 'avatar.png',
byte_size: '1234',
checksum: 'dsjbsdhbfif3874823mnsdbf',
content_type: 'image/png'
}
},
headers: { api_access_token: agent.access_token.token },
as: :json
context 'with a valid full-scope access token' do
it 'creates the direct upload blob' do
expect { upload(headers: { api_access_token: agent.access_token.token }) }
.to change(ActiveStorage::Blob, :count).by(1)
expect(response).to have_http_status(:success)
json_response = response.parsed_body
expect(json_response['content_type']).to eq('image/png')
expect(response.parsed_body['content_type']).to eq('image/png')
end
end
it 'rejects requests made with a read-only access token' do
read_only_token = agent.read_only_access_token
context 'without an access token' do
it 'returns unauthorized without creating a blob' do
expect { upload }.not_to change(ActiveStorage::Blob, :count)
post api_v1_account_conversation_direct_uploads_path(account_id: account.id, conversation_id: conversation.display_id),
params: {
blob: {
filename: 'avatar.png',
byte_size: '1234',
checksum: 'dsjbsdhbfif3874823mnsdbf',
content_type: 'image/png'
}
},
headers: { api_access_token: read_only_token.token },
as: :json
expect(response).to have_http_status(:unauthorized)
end
end
context 'with an invalid access token' do
it 'returns unauthorized without creating a blob' do
expect { upload(headers: { api_access_token: 'invalid-token' }) }
.not_to change(ActiveStorage::Blob, :count)
expect(response).to have_http_status(:unauthorized)
end
end
context 'with a read-only access token' do
it 'returns forbidden without creating a blob' do
expect { upload(headers: { api_access_token: agent.read_only_access_token.token }) }
.not_to change(ActiveStorage::Blob, :count)
expect(response).to have_http_status(:forbidden)
end