Extract Gitlab::Geo::BaseTransfer

parent f7c2df72
module Gitlab
module Geo
class BaseRequest
GITLAB_GEO_AUTH_TOKEN_TYPE = 'GL-Geo'.freeze
attr_reader :request_data
def initialize(request_data = {})
@request_data = request_data
end
def headers
{
'Authorization' => geo_auth_token(request_data)
}
end
private
def geo_auth_token(message)
geo_node = requesting_node
return unless geo_node
payload = { data: message.to_json, iat: Time.now.to_i }
token = JWT.encode(payload, geo_node.secret_access_key, 'HS256')
"#{GITLAB_GEO_AUTH_TOKEN_TYPE} #{geo_node.access_key}:#{token}"
end
def requesting_node
Gitlab::Geo.current_node
end
end
end
end
...@@ -16,7 +16,7 @@ module Gitlab ...@@ -16,7 +16,7 @@ module Gitlab
private private
def decode_geo_request def decode_geo_request
# A Geo transfer request has an Authorization header: # A Geo request has an Authorization header:
# Authorization: GL-Geo: <Geo Access Key>:<JWT payload> # Authorization: GL-Geo: <Geo Access Key>:<JWT payload>
# #
# For example: # For example:
...@@ -41,7 +41,7 @@ module Gitlab ...@@ -41,7 +41,7 @@ module Gitlab
data&.deep_symbolize_keys! data&.deep_symbolize_keys!
data data
rescue JWT::DecodeError => e rescue JWT::DecodeError => e
Rails.logger.error("Error decoding Geo transfer request: #{e}") Rails.logger.error("Error decoding Geo request: #{e}")
end end
end end
...@@ -58,7 +58,7 @@ module Gitlab ...@@ -58,7 +58,7 @@ module Gitlab
tokens = auth_header.split(' ') tokens = auth_header.split(' ')
return unless tokens.count == 2 return unless tokens.count == 2
return unless tokens[0] == Gitlab::Geo::TransferRequest::GITLAB_GEO_AUTH_TOKEN_TYPE return unless tokens[0] == Gitlab::Geo::BaseRequest::GITLAB_GEO_AUTH_TOKEN_TYPE
# Split at the first occurence of a colon # Split at the first occurence of a colon
geo_tokens = tokens[1].split(':', 2) geo_tokens = tokens[1].split(':', 2)
......
...@@ -20,11 +20,11 @@ module Gitlab ...@@ -20,11 +20,11 @@ module Gitlab
return unless primary return unless primary
url = primary.geo_transfers_url(file_type, file_id.to_s) url = primary.geo_transfers_url(file_type, file_id.to_s)
req_header = TransferRequest.new(request_data).header req_headers = TransferRequest.new(request_data).headers
return unless ensure_path_exists return unless ensure_path_exists
download_file(url, req_header) download_file(url, req_headers)
end end
private private
...@@ -56,12 +56,12 @@ module Gitlab ...@@ -56,12 +56,12 @@ module Gitlab
# Use HTTParty for now but switch to curb if performance becomes # Use HTTParty for now but switch to curb if performance becomes
# an issue # an issue
def download_file(url, req_header) def download_file(url, req_headers)
file_size = -1 file_size = -1
begin begin
File.open(filename, "wb") do |file| File.open(filename, "wb") do |file|
response = HTTParty.get(url, headers: req_header, stream_body: true) do |fragment| response = HTTParty.get(url, headers: req_headers, stream_body: true) do |fragment|
file.write(fragment) file.write(fragment)
end end
......
module Gitlab module Gitlab
module Geo module Geo
class TransferRequest class TransferRequest < BaseRequest
GITLAB_GEO_AUTH_TOKEN_TYPE = 'GL-Geo'.freeze def headers
super.merge({ 'X-Sendfile-Type' => 'X-Sendfile' })
attr_reader :request_data
def initialize(request_data)
@request_data = request_data
end
def header
{
"Authorization" => geo_transfer_auth(request_data.to_json),
"X-Sendfile-Type" => "X-Sendfile"
}
end
private
def geo_transfer_auth(message)
geo_node = requesting_node
return unless geo_node
payload = { data: message, iat: Time.now.to_i }
token = JWT.encode(payload, geo_node.secret_access_key, 'HS256')
"#{GITLAB_GEO_AUTH_TOKEN_TYPE} #{geo_node.access_key}:#{token}"
end
def requesting_node
Gitlab::Geo.current_node
end end
end end
end end
......
...@@ -5,7 +5,7 @@ describe Gitlab::Geo::JwtRequestDecoder do ...@@ -5,7 +5,7 @@ describe Gitlab::Geo::JwtRequestDecoder do
let(:data) { { input: 123 } } let(:data) { { input: 123 } }
let(:request) { Gitlab::Geo::TransferRequest.new(data) } let(:request) { Gitlab::Geo::TransferRequest.new(data) }
subject { described_class.new(request.header['Authorization']) } subject { described_class.new(request.headers['Authorization']) }
describe '#decode' do describe '#decode' do
it 'decodes correct data' do it 'decodes correct data' do
...@@ -13,7 +13,7 @@ describe Gitlab::Geo::JwtRequestDecoder do ...@@ -13,7 +13,7 @@ describe Gitlab::Geo::JwtRequestDecoder do
end end
it 'fails to decode with wrong key' do it 'fails to decode with wrong key' do
data = request.header['Authorization'] data = request.headers['Authorization']
primary_node.secret_access_key = '' primary_node.secret_access_key = ''
primary_node.save primary_node.save
......
...@@ -10,7 +10,7 @@ describe API::Geo, api: true do ...@@ -10,7 +10,7 @@ describe API::Geo, api: true do
end end
before(:each) do before(:each) do
allow(Gitlab::Geo).to receive(:current_node) { geo_node } allow(Gitlab::Geo).to receive(:current_node) { primary_node }
end end
describe 'POST /geo/receive_events authentication' do describe 'POST /geo/receive_events authentication' do
......
...@@ -5,7 +5,7 @@ describe Geo::FileUploadService, services: true do ...@@ -5,7 +5,7 @@ describe Geo::FileUploadService, services: true do
let(:params) { { id: lfs_object.id, type: 'lfs' } } let(:params) { { id: lfs_object.id, type: 'lfs' } }
let(:lfs_transfer) { Gitlab::Geo::LfsTransfer.new(lfs_object) } let(:lfs_transfer) { Gitlab::Geo::LfsTransfer.new(lfs_object) }
let(:transfer_request) { Gitlab::Geo::TransferRequest.new(lfs_transfer.request_data) } let(:transfer_request) { Gitlab::Geo::TransferRequest.new(lfs_transfer.request_data) }
let(:req_header) { transfer_request.header['Authorization'] } let(:req_header) { transfer_request.headers['Authorization'] }
before do before do
create(:geo_node, :current) create(:geo_node, :current)
......
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