Reject unconfirmed FASPs (#37926)

This commit is contained in:
David Roetzel
2026-02-20 15:40:31 +01:00
parent 7de301922b
commit b89d6e256b
11 changed files with 106 additions and 70 deletions

View File

@@ -47,7 +47,7 @@ class Api::Fasp::BaseController < ApplicationController
provider = nil provider = nil
Linzer.verify!(request.rack_request, no_older_than: 5.minutes) do |keyid| Linzer.verify!(request.rack_request, no_older_than: 5.minutes) do |keyid|
provider = Fasp::Provider.find(keyid) provider = Fasp::Provider.confirmed.find(keyid)
Linzer.new_ed25519_public_key(provider.provider_public_key_pem, keyid) Linzer.new_ed25519_public_key(provider.provider_public_key_pem, keyid)
end end

View File

@@ -34,6 +34,7 @@ class Fasp::Provider < ApplicationRecord
before_create :create_keypair before_create :create_keypair
after_commit :update_remote_capabilities after_commit :update_remote_capabilities
scope :confirmed, -> { where(confirmed: true) }
scope :with_capability, lambda { |capability_name| scope :with_capability, lambda { |capability_name|
where('fasp_providers.capabilities @> ?::jsonb', "[{\"id\": \"#{capability_name}\", \"enabled\": true}]") where('fasp_providers.capabilities @> ?::jsonb', "[{\"id\": \"#{capability_name}\", \"enabled\": true}]")
} }

View File

@@ -6,34 +6,33 @@ RSpec.describe 'Api::Fasp::DataSharing::V0::BackfillRequests', feature: :fasp do
include ProviderRequestHelper include ProviderRequestHelper
describe 'POST /api/fasp/data_sharing/v0/backfill_requests' do describe 'POST /api/fasp/data_sharing/v0/backfill_requests' do
let(:provider) { Fabricate(:fasp_provider) } subject do
post api_fasp_data_sharing_v0_backfill_requests_path, headers:, params:, as: :json
end
let(:provider) { Fabricate(:confirmed_fasp) }
let(:params) { { category: 'content', maxCount: 10 } }
let(:headers) do
request_authentication_headers(provider,
url: api_fasp_data_sharing_v0_backfill_requests_url,
method: :post,
body: params)
end
it_behaves_like 'forbidden for unconfirmed provider'
context 'with valid parameters' do context 'with valid parameters' do
it 'creates a new backfill request' do it 'creates a new backfill request' do
params = { category: 'content', maxCount: 10 } expect { subject }.to change(Fasp::BackfillRequest, :count).by(1)
headers = request_authentication_headers(provider,
url: api_fasp_data_sharing_v0_backfill_requests_url,
method: :post,
body: params)
expect do
post api_fasp_data_sharing_v0_backfill_requests_path, headers:, params:, as: :json
end.to change(Fasp::BackfillRequest, :count).by(1)
expect(response).to have_http_status(201) expect(response).to have_http_status(201)
end end
end end
context 'with invalid parameters' do context 'with invalid parameters' do
it 'does not create a backfill request' do let(:params) { { category: 'unknown', maxCount: 10 } }
params = { category: 'unknown', maxCount: 10 }
headers = request_authentication_headers(provider,
url: api_fasp_data_sharing_v0_backfill_requests_url,
method: :post,
body: params)
expect do it 'does not create a backfill request' do
post api_fasp_data_sharing_v0_backfill_requests_path, headers:, params:, as: :json expect { subject }.to_not change(Fasp::BackfillRequest, :count)
end.to_not change(Fasp::BackfillRequest, :count)
expect(response).to have_http_status(422) expect(response).to have_http_status(422)
end end
end end

View File

@@ -6,15 +6,22 @@ RSpec.describe 'Api::Fasp::DataSharing::V0::Continuations', feature: :fasp do
include ProviderRequestHelper include ProviderRequestHelper
describe 'POST /api/fasp/data_sharing/v0/backfill_requests/:id/continuations' do describe 'POST /api/fasp/data_sharing/v0/backfill_requests/:id/continuations' do
let(:backfill_request) { Fabricate(:fasp_backfill_request) } subject do
let(:provider) { backfill_request.fasp_provider } post api_fasp_data_sharing_v0_backfill_request_continuation_path(backfill_request), headers:, as: :json
end
let(:provider) { Fabricate(:confirmed_fasp) }
let(:backfill_request) { Fabricate(:fasp_backfill_request, fasp_provider: provider) }
let(:headers) do
request_authentication_headers(provider,
url: api_fasp_data_sharing_v0_backfill_request_continuation_url(backfill_request),
method: :post)
end
it_behaves_like 'forbidden for unconfirmed provider'
it 'queues a job to continue the given backfill request' do it 'queues a job to continue the given backfill request' do
headers = request_authentication_headers(provider, subject
url: api_fasp_data_sharing_v0_backfill_request_continuation_url(backfill_request),
method: :post)
post api_fasp_data_sharing_v0_backfill_request_continuation_path(backfill_request), headers:, as: :json
expect(response).to have_http_status(204) expect(response).to have_http_status(204)
expect(Fasp::BackfillWorker).to have_enqueued_sidekiq_job(backfill_request.id) expect(Fasp::BackfillWorker).to have_enqueued_sidekiq_job(backfill_request.id)
end end

View File

@@ -6,51 +6,57 @@ RSpec.describe 'Api::Fasp::DataSharing::V0::EventSubscriptions', feature: :fasp
include ProviderRequestHelper include ProviderRequestHelper
describe 'POST /api/fasp/data_sharing/v0/event_subscriptions' do describe 'POST /api/fasp/data_sharing/v0/event_subscriptions' do
let(:provider) { Fabricate(:fasp_provider) } subject do
post api_fasp_data_sharing_v0_event_subscriptions_path, headers:, params:, as: :json
end
let(:provider) { Fabricate(:confirmed_fasp) }
let(:params) { { category: 'content', subscriptionType: 'lifecycle', maxBatchSize: 10 } }
let(:headers) do
request_authentication_headers(provider,
url: api_fasp_data_sharing_v0_event_subscriptions_url,
method: :post,
body: params)
end
it_behaves_like 'forbidden for unconfirmed provider'
context 'with valid parameters' do context 'with valid parameters' do
it 'creates a new subscription' do it 'creates a new subscription' do
params = { category: 'content', subscriptionType: 'lifecycle', maxBatchSize: 10 }
headers = request_authentication_headers(provider,
url: api_fasp_data_sharing_v0_event_subscriptions_url,
method: :post,
body: params)
expect do expect do
post api_fasp_data_sharing_v0_event_subscriptions_path, headers:, params:, as: :json subject
end.to change(Fasp::Subscription, :count).by(1) end.to change(Fasp::Subscription, :count).by(1)
expect(response).to have_http_status(201) expect(response).to have_http_status(201)
end end
end end
context 'with invalid parameters' do context 'with invalid parameters' do
it 'does not create a subscription' do let(:params) { { category: 'unknown' } }
params = { category: 'unknown' }
headers = request_authentication_headers(provider,
url: api_fasp_data_sharing_v0_event_subscriptions_url,
method: :post,
body: params)
expect do it 'does not create a subscription' do
post api_fasp_data_sharing_v0_event_subscriptions_path, headers:, params:, as: :json expect { subject }.to_not change(Fasp::Subscription, :count)
end.to_not change(Fasp::Subscription, :count)
expect(response).to have_http_status(422) expect(response).to have_http_status(422)
end end
end end
end end
describe 'DELETE /api/fasp/data_sharing/v0/event_subscriptions/:id' do describe 'DELETE /api/fasp/data_sharing/v0/event_subscriptions/:id' do
let(:subscription) { Fabricate(:fasp_subscription) } subject do
let(:provider) { subscription.fasp_provider } delete api_fasp_data_sharing_v0_event_subscription_path(subscription), headers:, as: :json
end
let(:provider) { Fabricate(:confirmed_fasp) }
let!(:subscription) { Fabricate(:fasp_subscription, fasp_provider: provider) }
let(:headers) do
request_authentication_headers(provider,
url: api_fasp_data_sharing_v0_event_subscription_url(subscription),
method: :delete)
end
it_behaves_like 'forbidden for unconfirmed provider'
it 'deletes the subscription' do it 'deletes the subscription' do
headers = request_authentication_headers(provider, expect { subject }.to change(Fasp::Subscription, :count).by(-1)
url: api_fasp_data_sharing_v0_event_subscription_url(subscription),
method: :delete)
expect do
delete api_fasp_data_sharing_v0_event_subscription_path(subscription), headers:, as: :json
end.to change(Fasp::Subscription, :count).by(-1)
expect(response).to have_http_status(204) expect(response).to have_http_status(204)
end end
end end

View File

@@ -6,18 +6,23 @@ RSpec.describe 'Api::Fasp::Debug::V0::Callback::Responses', feature: :fasp do
include ProviderRequestHelper include ProviderRequestHelper
describe 'POST /api/fasp/debug/v0/callback/responses' do describe 'POST /api/fasp/debug/v0/callback/responses' do
let(:provider) { Fabricate(:debug_fasp) } subject do
post api_fasp_debug_v0_callback_responses_path, headers:, params: payload, as: :json
end
let(:provider) { Fabricate(:confirmed_fasp) }
let(:payload) { { test: 'call' } }
let(:headers) do
request_authentication_headers(provider,
url: api_fasp_debug_v0_callback_responses_url,
method: :post,
body: payload)
end
it_behaves_like 'forbidden for unconfirmed provider'
it 'create a record of the callback' do it 'create a record of the callback' do
payload = { test: 'call' } expect { subject }.to change(Fasp::DebugCallback, :count).by(1)
headers = request_authentication_headers(provider,
url: api_fasp_debug_v0_callback_responses_url,
method: :post,
body: payload)
expect do
post api_fasp_debug_v0_callback_responses_path, headers:, params: payload, as: :json
end.to change(Fasp::DebugCallback, :count).by(1)
expect(response).to have_http_status(201) expect(response).to have_http_status(201)
debug_callback = Fasp::DebugCallback.last debug_callback = Fasp::DebugCallback.last

View File

@@ -0,0 +1,13 @@
# frozen_string_literal: true
RSpec.shared_examples 'forbidden for unconfirmed provider' do
context 'when the requesting provider is unconfirmed' do
let(:provider) { Fabricate(:fasp_provider) }
it 'returns http unauthorized' do
subject
expect(response).to have_http_status(401)
end
end
end

View File

@@ -6,10 +6,11 @@ RSpec.describe Fasp::AnnounceAccountLifecycleEventWorker do
include ProviderRequestHelper include ProviderRequestHelper
let(:account_uri) { 'https://masto.example.com/accounts/1' } let(:account_uri) { 'https://masto.example.com/accounts/1' }
let(:provider) { Fabricate(:confirmed_fasp) }
let(:subscription) do let(:subscription) do
Fabricate(:fasp_subscription, category: 'account') Fabricate(:fasp_subscription, fasp_provider: provider, category: 'account')
end end
let(:provider) { subscription.fasp_provider }
let!(:stubbed_request) do let!(:stubbed_request) do
stub_provider_request(provider, stub_provider_request(provider,
method: :post, method: :post,

View File

@@ -6,10 +6,11 @@ RSpec.describe Fasp::AnnounceContentLifecycleEventWorker do
include ProviderRequestHelper include ProviderRequestHelper
let(:status_uri) { 'https://masto.example.com/status/1' } let(:status_uri) { 'https://masto.example.com/status/1' }
let(:provider) { Fabricate(:confirmed_fasp) }
let(:subscription) do let(:subscription) do
Fabricate(:fasp_subscription) Fabricate(:fasp_subscription, fasp_provider: provider)
end end
let(:provider) { subscription.fasp_provider }
let!(:stubbed_request) do let!(:stubbed_request) do
stub_provider_request(provider, stub_provider_request(provider,
method: :post, method: :post,

View File

@@ -6,14 +6,15 @@ RSpec.describe Fasp::AnnounceTrendWorker do
include ProviderRequestHelper include ProviderRequestHelper
let(:status) { Fabricate(:status) } let(:status) { Fabricate(:status) }
let(:provider) { Fabricate(:confirmed_fasp) }
let(:subscription) do let(:subscription) do
Fabricate(:fasp_subscription, Fabricate(:fasp_subscription,
fasp_provider: provider,
category: 'content', category: 'content',
subscription_type: 'trends', subscription_type: 'trends',
threshold_timeframe: 15, threshold_timeframe: 15,
threshold_likes: 2) threshold_likes: 2)
end end
let(:provider) { subscription.fasp_provider }
let!(:stubbed_request) do let!(:stubbed_request) do
stub_provider_request(provider, stub_provider_request(provider,
method: :post, method: :post,

View File

@@ -5,8 +5,10 @@ require 'rails_helper'
RSpec.describe Fasp::BackfillWorker do RSpec.describe Fasp::BackfillWorker do
include ProviderRequestHelper include ProviderRequestHelper
let(:backfill_request) { Fabricate(:fasp_backfill_request) } subject { described_class.new.perform(backfill_request.id) }
let(:provider) { backfill_request.fasp_provider }
let(:provider) { Fabricate(:confirmed_fasp) }
let(:backfill_request) { Fabricate(:fasp_backfill_request, fasp_provider: provider) }
let(:status) { Fabricate(:status) } let(:status) { Fabricate(:status) }
let!(:stubbed_request) do let!(:stubbed_request) do
stub_provider_request(provider, stub_provider_request(provider,