Reject unconfirmed FASPs (#37926)
This commit is contained in:
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -37,6 +37,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}]")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ class Fasp::BaseWorker
|
|||||||
private
|
private
|
||||||
|
|
||||||
def with_provider(provider)
|
def with_provider(provider)
|
||||||
return unless provider.available?
|
return unless provider.confirmed? && provider.available?
|
||||||
|
|
||||||
yield
|
yield
|
||||||
rescue *Mastodon::HTTP_CONNECTION_ERRORS
|
rescue *Mastodon::HTTP_CONNECTION_ERRORS
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
13
spec/support/examples/fasp/api.rb
Normal file
13
spec/support/examples/fasp/api.rb
Normal 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
|
||||||
@@ -8,10 +8,10 @@ RSpec.describe Fasp::AnnounceAccountLifecycleEventWorker do
|
|||||||
subject { described_class.new.perform(account_uri, 'new') }
|
subject { described_class.new.perform(account_uri, 'new') }
|
||||||
|
|
||||||
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(:path) { '/data_sharing/v0/announcements' }
|
let(:path) { '/data_sharing/v0/announcements' }
|
||||||
|
|
||||||
let!(:stubbed_request) do
|
let!(:stubbed_request) do
|
||||||
|
|||||||
@@ -8,10 +8,10 @@ RSpec.describe Fasp::AnnounceContentLifecycleEventWorker do
|
|||||||
subject { described_class.new.perform(status_uri, 'new') }
|
subject { described_class.new.perform(status_uri, 'new') }
|
||||||
|
|
||||||
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(:path) { '/data_sharing/v0/announcements' }
|
let(:path) { '/data_sharing/v0/announcements' }
|
||||||
|
|
||||||
let!(:stubbed_request) do
|
let!(:stubbed_request) do
|
||||||
|
|||||||
@@ -8,14 +8,15 @@ RSpec.describe Fasp::AnnounceTrendWorker do
|
|||||||
subject { described_class.new.perform(status.id, 'favourite') }
|
subject { described_class.new.perform(status.id, 'favourite') }
|
||||||
|
|
||||||
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(:path) { '/data_sharing/v0/announcements' }
|
let(:path) { '/data_sharing/v0/announcements' }
|
||||||
|
|
||||||
let!(:stubbed_request) do
|
let!(:stubbed_request) do
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ RSpec.describe Fasp::BackfillWorker do
|
|||||||
|
|
||||||
subject { described_class.new.perform(backfill_request.id) }
|
subject { described_class.new.perform(backfill_request.id) }
|
||||||
|
|
||||||
let(:backfill_request) { Fabricate(:fasp_backfill_request) }
|
let(:provider) { Fabricate(:confirmed_fasp) }
|
||||||
let(:provider) { backfill_request.fasp_provider }
|
let(:backfill_request) { Fabricate(:fasp_backfill_request, fasp_provider: provider) }
|
||||||
let(:status) { Fabricate(:status) }
|
let(:status) { Fabricate(:status) }
|
||||||
let(:path) { '/data_sharing/v0/announcements' }
|
let(:path) { '/data_sharing/v0/announcements' }
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user