diff options
author | Starfall <us@starfall.systems> | 2023-04-14 19:22:47 -0500 |
---|---|---|
committer | Starfall <us@starfall.systems> | 2023-04-14 19:22:47 -0500 |
commit | 4fe1689de43f4404eb9530fcfbcbfb26d6c1c13a (patch) | |
tree | 6811b845bb7f4966b10dcefa3dea404246f161c7 /spec/controllers/concerns | |
parent | 65c1e53a32cabcdbb7bca57002bb0f6acdebe07e (diff) | |
parent | bed63f6dae0879ac840066b031229e0d139089cd (diff) |
Diffstat (limited to 'spec/controllers/concerns')
-rw-r--r-- | spec/controllers/concerns/export_controller_concern_spec.rb | 2 | ||||
-rw-r--r-- | spec/controllers/concerns/signature_verification_spec.rb | 107 |
2 files changed, 101 insertions, 8 deletions
diff --git a/spec/controllers/concerns/export_controller_concern_spec.rb b/spec/controllers/concerns/export_controller_concern_spec.rb index 1a5e46f8e..003fd17f6 100644 --- a/spec/controllers/concerns/export_controller_concern_spec.rb +++ b/spec/controllers/concerns/export_controller_concern_spec.rb @@ -29,7 +29,7 @@ describe ApplicationController, type: :controller do it 'returns unauthorized when not signed in' do get :index, format: :csv - expect(response).to have_http_status(:unauthorized) + expect(response).to have_http_status(401) end end end diff --git a/spec/controllers/concerns/signature_verification_spec.rb b/spec/controllers/concerns/signature_verification_spec.rb index 6e73643b4..13655f313 100644 --- a/spec/controllers/concerns/signature_verification_spec.rb +++ b/spec/controllers/concerns/signature_verification_spec.rb @@ -16,6 +16,8 @@ describe ApplicationController, type: :controller do controller do include SignatureVerification + before_action :require_actor_signature!, only: [:signature_required] + def success head 200 end @@ -23,10 +25,17 @@ describe ApplicationController, type: :controller do def alternative_success head 200 end + + def signature_required + head 200 + end end before do - routes.draw { match via: [:get, :post], 'success' => 'anonymous#success' } + routes.draw do + match via: [:get, :post], 'success' => 'anonymous#success' + match via: [:get, :post], 'signature_required' => 'anonymous#signature_required' + end end context 'without signature header' do @@ -118,6 +127,37 @@ describe ApplicationController, type: :controller do end end + context 'with request with unparseable Date header' do + before do + get :success + + fake_request = Request.new(:get, request.url) + fake_request.add_headers({ 'Date' => 'wrong date' }) + fake_request.on_behalf_of(author) + + request.headers.merge!(fake_request.headers) + end + + describe '#signed_request?' do + it 'returns true' do + expect(controller.signed_request?).to be true + end + end + + describe '#signed_request_account' do + it 'returns nil' do + expect(controller.signed_request_account).to be_nil + end + end + + describe '#signature_verification_failure_reason' do + it 'contains an error description' do + controller.signed_request_account + expect(controller.signature_verification_failure_reason[:error]).to eq 'Invalid Date header: not RFC 2616 compliant date: "wrong date"' + end + end + end + context 'with request older than a day' do before do get :success @@ -140,6 +180,13 @@ describe ApplicationController, type: :controller do expect(controller.signed_request_account).to be_nil end end + + describe '#signature_verification_failure_reason' do + it 'contains an error description' do + controller.signed_request_account + expect(controller.signature_verification_failure_reason[:error]).to eq 'Signed request date outside acceptable time window' + end + end end context 'with inaccessible key' do @@ -171,6 +218,7 @@ describe ApplicationController, type: :controller do context 'with body' do before do + allow(controller).to receive(:actor_refresh_key!).and_return(author) post :success, body: 'Hello world' fake_request = Request.new(:post, request.url, body: 'Hello world') @@ -189,21 +237,66 @@ describe ApplicationController, type: :controller do it 'returns an account' do expect(controller.signed_request_account).to eq author end + end - it 'returns nil when path does not match' do + context 'when path does not match' do + before do request.path = '/alternative-path' - expect(controller.signed_request_account).to be_nil end - it 'returns nil when method does not match' do + describe '#signed_request_account' do + it 'returns nil' do + expect(controller.signed_request_account).to be_nil + end + end + + describe '#signature_verification_failure_reason' do + it 'contains an error description' do + controller.signed_request_account + expect(controller.signature_verification_failure_reason[:error]).to include('using rsa-sha256 (RSASSA-PKCS1-v1_5 with SHA-256)') + expect(controller.signature_verification_failure_reason[:signed_string]).to include("(request-target): post /alternative-path\n") + end + end + end + + context 'when method does not match' do + before do get :success - expect(controller.signed_request_account).to be_nil end - it 'returns nil when body has been tampered' do + describe '#signed_request_account' do + it 'returns nil' do + expect(controller.signed_request_account).to be_nil + end + end + end + + context 'when body has been tampered' do + before do post :success, body: 'doo doo doo' - expect(controller.signed_request_account).to be_nil end + + describe '#signed_request_account' do + it 'returns nil when body has been tampered' do + expect(controller.signed_request_account).to be_nil + end + end + end + end + end + + context 'when a signature is required' do + before do + get :signature_required + end + + context 'without signature header' do + it 'returns HTTP 401' do + expect(response).to have_http_status(401) + end + + it 'returns an error' do + expect(Oj.load(response.body)['error']).to eq 'Request not signed' end end end |