Commit 05e24ce6 authored by Stan Hu's avatar Stan Hu

Gracefully handle case when Geo secondary does not have the right db_key_base

If the admin uses the wrong db_key_base on the secondary, an obscure OpenSSL
error shows up on the secondary and results in an Error 500. This change
helps make it more obvious to admins what needs to be fixed.

Closes #2181
parent 149a535b
---
title: Gracefully handle case when Geo secondary does not have the right db_key_base
merge_request:
author:
...@@ -94,9 +94,13 @@ module API ...@@ -94,9 +94,13 @@ module API
def authenticate_by_gitlab_geo_node_token! def authenticate_by_gitlab_geo_node_token!
auth_header = headers['Authorization'] auth_header = headers['Authorization']
begin
unless auth_header && Gitlab::Geo::JwtRequestDecoder.new(auth_header).decode unless auth_header && Gitlab::Geo::JwtRequestDecoder.new(auth_header).decode
unauthorized! unauthorized!
end end
rescue Gitlab::Geo::InvalidDecryptionKeyError => e
render_api_error!(e.to_s, 401)
end
end end
def require_node_to_be_enabled! def require_node_to_be_enabled!
......
module Gitlab module Gitlab
module Geo module Geo
InvalidDecryptionKeyError = Class.new(StandardError)
class JwtRequestDecoder class JwtRequestDecoder
IAT_LEEWAY = 60.seconds.to_i IAT_LEEWAY = 60.seconds.to_i
...@@ -22,7 +24,13 @@ module Gitlab ...@@ -22,7 +24,13 @@ module Gitlab
# For example: # For example:
# JWT payload = { "data": { "oid": "12345" }, iat: 123456 } # JWT payload = { "data": { "oid": "12345" }, iat: 123456 }
# #
begin
data = decode_auth_header data = decode_auth_header
rescue OpenSSL::Cipher::CipherError
message = 'Error decrypting the Geo secret from the database. Check that the primary and secondary have the same db_key_base.'
Rails.logger.error(message)
raise InvalidDecryptionKeyError.new(message)
end
return unless data.present? return unless data.present?
......
...@@ -32,5 +32,11 @@ describe Gitlab::Geo::JwtRequestDecoder do ...@@ -32,5 +32,11 @@ describe Gitlab::Geo::JwtRequestDecoder do
expect(subject.decode).to be_nil expect(subject.decode).to be_nil
end end
it 'raises invalid decryption key error' do
allow_any_instance_of(described_class).to receive(:decode_auth_header).and_raise(Gitlab::Geo::InvalidDecryptionKeyError)
expect { subject.decode }.to raise_error(Gitlab::Geo::InvalidDecryptionKeyError)
end
end end
end end
...@@ -287,6 +287,14 @@ describe API::Geo, api: true do ...@@ -287,6 +287,14 @@ describe API::Geo, api: true do
expect(response).to have_http_status(401) expect(response).to have_http_status(401)
end end
it 'responds with 401 when the db_key_base is wrong' do
allow_any_instance_of(Gitlab::Geo::JwtRequestDecoder).to receive(:decode).and_raise(Gitlab::Geo::InvalidDecryptionKeyError)
get api('/geo/status'), nil, request.headers
expect(response).to have_http_status(401)
end
context 'when requesting secondary node with valid auth header' do context 'when requesting secondary node with valid auth header' do
before(:each) do before(:each) do
allow(Gitlab::Geo).to receive(:current_node) { secondary_node } allow(Gitlab::Geo).to receive(:current_node) { secondary_node }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment