Skip to content
Snippets Groups Projects
Verified Commit 4492cc4a authored by Halil Coban's avatar Halil Coban :two: Committed by GitLab
Browse files

Secure gRPC connections in Duo Workflow Service ruby client

parent 9ad0dd18
No related branches found
No related tags found
2 merge requests!164749Enable parallel in test-on-omnibus,!162696Secure gRPC connections in Duo Workflow Service ruby client
......@@ -7,17 +7,16 @@ module Ai
module DuoWorkflow
module DuoWorkflowService
class Client
def initialize(duo_workflow_service_url:, current_user:)
def initialize(duo_workflow_service_url:, current_user:, secure:)
@duo_workflow_service_url = duo_workflow_service_url
@current_user = current_user
@secure = secure
end
def generate_token
# TODO: use secure channel for non-localhost URLs
stub = ::DuoWorkflowService::DuoWorkflow::Stub.new(
duo_workflow_service_url,
:this_channel_is_insecure
channel_credentials
)
request = ::DuoWorkflowService::GenerateTokenRequest.new
......@@ -55,6 +54,14 @@ def token
scopes: ["duo_workflow_generate_token"]
).encoded
end
def channel_credentials
if @secure
GRPC::Core::ChannelCredentials.new(::Gitlab::X509::Certificate.ca_certs_bundle)
else
:this_channel_is_insecure
end
end
end
end
end
......
......@@ -49,7 +49,10 @@ def authorize_run_workflows!(project)
end
duo_workflow_token_result = ::Ai::DuoWorkflow::DuoWorkflowService::Client.new(
duo_workflow_service_url: Gitlab::DuoWorkflow::Client.url, current_user: current_user).generate_token
duo_workflow_service_url: Gitlab::DuoWorkflow::Client.url,
current_user: current_user,
secure: Gitlab::DuoWorkflow::Client.secure?
).generate_token
bad_request!(duo_workflow_token_result[:message]) if duo_workflow_token_result[:status] == :error
......
......@@ -22,6 +22,14 @@ def self.cloud_connector_url
nil
end
def self.secure?
return false unless cloud_connector_url
# Since Duo Workflow Service grpc url is inferred from Cloud Connector
# it won't have grpcs or tls scheme, instead it may have https scheme
URI.parse(cloud_connector_url).scheme == 'https'
end
end
end
end
......@@ -5,14 +5,17 @@
RSpec.describe Ai::DuoWorkflow::DuoWorkflowService::Client, feature_category: :duo_workflow do
let_it_be(:current_user) { create(:user) }
let(:duo_workflow_service_url) { 'example.com:443' }
let(:secure) { true }
let(:stub) { instance_double('DuoWorkflowService::DuoWorkflow::Stub') }
let(:request) { instance_double('DuoWorkflowService::GenerateTokenRequest') }
let(:response) { double(token: 'a user jwt', expiresAt: 'a timestamp') } # rubocop:disable RSpec/VerifiedDoubles -- instance_double keeps raising error the DuoWorkflowService::GenerateTokenResponse class does not implement the class method: token
let(:channel_credentials) { instance_of(GRPC::Core::ChannelCredentials) }
subject(:client) do
described_class.new(
duo_workflow_service_url: duo_workflow_service_url,
current_user: current_user
current_user: current_user,
secure: secure
)
end
......@@ -20,7 +23,7 @@
allow_next_instance_of(::Gitlab::CloudConnector::SelfIssuedToken) do |token|
allow(token).to receive(:encoded).and_return('instance jwt')
end
allow(DuoWorkflowService::DuoWorkflow::Stub).to receive(:new).and_return(stub)
allow(DuoWorkflowService::DuoWorkflow::Stub).to receive(:new).with(anything, channel_credentials).and_return(stub)
allow(stub).to receive(:generate_token).and_return(response)
allow(DuoWorkflowService::GenerateTokenRequest).to receive(:new).and_return(request)
end
......@@ -50,6 +53,17 @@
expect(result.payload[:expires_at]).to eq('a timestamp')
end
context 'when secure is false' do
let(:secure) { false }
let(:channel_credentials) { :this_channel_is_insecure }
it 'calls with insecure channel credentials' do
result = client.generate_token
expect(result).to be_success
end
end
context 'when an error occurs' do
before do
allow(stub).to receive(:generate_token).and_raise(StandardError.new('Test error'))
......
......@@ -41,4 +41,32 @@
end
end
end
describe '.secure?' do
context 'when cloud_connector is configured to https' do
it 'returns true' do
expect(described_class.secure?).to eq(true)
end
end
context 'when cloud_connector is configured to http' do
before do
allow(Gitlab.config.cloud_connector).to receive(:base_url).and_return 'http://duo-workflow-service.example.com'
end
it 'returns false' do
expect(described_class.secure?).to eq(false)
end
end
context 'when cloud_connector is not configured' do
before do
allow(Gitlab.config).to receive(:cloud_connector).and_raise(GitlabSettings::MissingSetting)
end
it 'returns nil' do
expect(described_class.secure?).to eq(false)
end
end
end
end
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment