Skip to content

Commit 4d87f3b

Browse files
jacobvosmaersmcgivern
authored andcommitted
Retrieve commit signatures with Gitaly
1 parent ee58763 commit 4d87f3b

File tree

8 files changed

+156
-41
lines changed

8 files changed

+156
-41
lines changed

GITALY_SERVER_VERSION

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0.69.0
1+
0.70.0

app/controllers/projects/commits_controller.rb

+26-20
Original file line numberDiff line numberDiff line change
@@ -13,31 +13,37 @@ def show
1313
@merge_request = MergeRequestsFinder.new(current_user, project_id: @project.id).execute.opened
1414
.find_by(source_project: @project, source_branch: @ref, target_branch: @repository.root_ref)
1515

16-
respond_to do |format|
17-
format.html
18-
format.atom { render layout: 'xml.atom' }
19-
20-
format.json do
21-
pager_json(
22-
'projects/commits/_commits',
23-
@commits.size,
24-
project: @project,
25-
ref: @ref)
16+
# https://gitlab.com/gitlab-org/gitaly/issues/931
17+
Gitlab::GitalyClient.allow_n_plus_1_calls do
18+
respond_to do |format|
19+
format.html
20+
format.atom { render layout: 'xml.atom' }
21+
22+
format.json do
23+
pager_json(
24+
'projects/commits/_commits',
25+
@commits.size,
26+
project: @project,
27+
ref: @ref)
28+
end
2629
end
2730
end
2831
end
2932

3033
def signatures
31-
respond_to do |format|
32-
format.json do
33-
render json: {
34-
signatures: @commits.select(&:has_signature?).map do |commit|
35-
{
36-
commit_sha: commit.sha,
37-
html: view_to_html_string('projects/commit/_signature', signature: commit.signature)
38-
}
39-
end
40-
}
34+
# https://gitlab.com/gitlab-org/gitaly/issues/931
35+
Gitlab::GitalyClient.allow_n_plus_1_calls do
36+
respond_to do |format|
37+
format.json do
38+
render json: {
39+
signatures: @commits.select(&:has_signature?).map do |commit|
40+
{
41+
commit_sha: commit.sha,
42+
html: view_to_html_string('projects/commit/_signature', signature: commit.signature)
43+
}
44+
end
45+
}
46+
end
4147
end
4248
end
4349
end

lib/gitlab/git/commit.rb

+18
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,24 @@ def batch_by_oid(repo, oids)
239239
end
240240
end
241241
end
242+
243+
def extract_signature(repository, commit_id)
244+
repository.gitaly_migrate(:extract_commit_signature) do |is_enabled|
245+
if is_enabled
246+
repository.gitaly_commit_client.extract_signature(commit_id)
247+
else
248+
rugged_extract_signature(repository, commit_id)
249+
end
250+
end
251+
end
252+
253+
def rugged_extract_signature(repository, commit_id)
254+
begin
255+
Rugged::Commit.extract_signature(repository.rugged, commit_id)
256+
rescue Rugged::OdbError
257+
nil
258+
end
259+
end
242260
end
243261

244262
def initialize(repository, raw_commit, head = nil)

lib/gitlab/gitaly_client/commit_service.rb

+17
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,23 @@ def filter_shas_with_signatures(shas)
282282
end
283283
end
284284

285+
def extract_signature(commit_id)
286+
request = Gitaly::ExtractCommitSignatureRequest.new(repository: @gitaly_repo, commit_id: commit_id)
287+
response = GitalyClient.call(@repository.storage, :commit_service, :extract_commit_signature, request)
288+
289+
signature = ''.b
290+
signed_text = ''.b
291+
292+
response.each do |message|
293+
signature << message.signature
294+
signed_text << message.signed_text
295+
end
296+
297+
return if signature.blank? && signed_text.blank?
298+
299+
[signature, signed_text]
300+
end
301+
285302
private
286303

287304
def call_commit_diff(request_params, options = {})

lib/gitlab/gpg/commit.rb

+2-6
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,8 @@ class Commit
44
def initialize(commit)
55
@commit = commit
66

7-
@signature_text, @signed_text =
8-
begin
9-
Rugged::Commit.extract_signature(@commit.project.repository.rugged, @commit.sha)
10-
rescue Rugged::OdbError
11-
nil
12-
end
7+
repo = commit.project.repository.raw_repository
8+
@signature_text, @signed_text = Gitlab::Git::Commit.extract_signature(repo, commit.sha)
139
end
1410

1511
def has_signature?

spec/lib/gitlab/git/commit_spec.rb

+78
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,84 @@
388388
end
389389
end
390390
end
391+
392+
describe '.extract_signature' do
393+
subject { described_class.extract_signature(repository, commit_id) }
394+
395+
shared_examples '.extract_signature' do
396+
context 'when the commit is signed' do
397+
let(:commit_id) { '0b4bc9a49b562e85de7cc9e834518ea6828729b9' }
398+
399+
it 'returns signature and signed text' do
400+
signature, signed_text = subject
401+
402+
expected_signature = <<~SIGNATURE
403+
-----BEGIN PGP SIGNATURE-----
404+
Version: GnuPG/MacGPG2 v2.0.22 (Darwin)
405+
Comment: GPGTools - https://gpgtools.org
406+
407+
iQEcBAABCgAGBQJTDvaZAAoJEGJ8X1ifRn8XfvYIAMuB0yrbTGo1BnOSoDfyrjb0
408+
Kw2EyUzvXYL72B63HMdJ+/0tlSDC6zONF3fc+bBD8z+WjQMTbwFNMRbSSy2rKEh+
409+
mdRybOP3xBIMGgEph0/kmWln39nmFQBsPRbZBWoU10VfI/ieJdEOgOphszgryRar
410+
TyS73dLBGE9y9NIININVaNISet9D9QeXFqc761CGjh4YIghvPpi+YihMWapGka6v
411+
hgKhX+hc5rj+7IEE0CXmlbYR8OYvAbAArc5vJD7UTxAY4Z7/l9d6Ydt9GQ25khfy
412+
ANFgltYzlR6evLFmDjssiP/mx/ZMN91AL0ueJ9nNGv411Mu2CUW+tDCaQf35mdc=
413+
=j51i
414+
-----END PGP SIGNATURE-----
415+
SIGNATURE
416+
417+
expect(signature).to eq(expected_signature.chomp)
418+
expect(signature).to be_a_binary_string
419+
420+
expected_signed_text = <<~SIGNED_TEXT
421+
tree 22bfa2fbd217df24731f43ff43a4a0f8db759dae
422+
parent ae73cb07c9eeaf35924a10f713b364d32b2dd34f
423+
author Dmitriy Zaporozhets <[email protected]> 1393489561 +0200
424+
committer Dmitriy Zaporozhets <[email protected]> 1393489561 +0200
425+
426+
Feature added
427+
428+
Signed-off-by: Dmitriy Zaporozhets <[email protected]>
429+
SIGNED_TEXT
430+
431+
expect(signed_text).to eq(expected_signed_text)
432+
expect(signed_text).to be_a_binary_string
433+
end
434+
end
435+
436+
context 'when the commit has no signature' do
437+
let(:commit_id) { '4b4918a572fa86f9771e5ba40fbd48e1eb03e2c6' }
438+
439+
it 'returns nil' do
440+
expect(subject).to be_nil
441+
end
442+
end
443+
444+
context 'when the commit cannot be found' do
445+
let(:commit_id) { Gitlab::Git::BLANK_SHA }
446+
447+
it 'returns nil' do
448+
expect(subject).to be_nil
449+
end
450+
end
451+
452+
context 'when the commit ID is invalid' do
453+
let(:commit_id) { '4b4918a572fa86f9771e5ba40fbd48e' }
454+
455+
it 'raises ArgumentError' do
456+
expect { subject }.to raise_error(ArgumentError)
457+
end
458+
end
459+
end
460+
461+
context 'with gitaly' do
462+
it_behaves_like '.extract_signature'
463+
end
464+
465+
context 'without gitaly', :skip_gitaly_mock do
466+
it_behaves_like '.extract_signature'
467+
end
468+
end
391469
end
392470

393471
describe '#init_from_rugged' do

spec/lib/gitlab/gpg/commit_spec.rb

+12-12
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@
3838
end
3939

4040
before do
41-
allow(Rugged::Commit).to receive(:extract_signature)
42-
.with(Rugged::Repository, commit_sha)
41+
allow(Gitlab::Git::Commit).to receive(:extract_signature)
42+
.with(Gitlab::Git::Repository, commit_sha)
4343
.and_return(
4444
[
4545
GpgHelpers::User1.signed_commit_signature,
@@ -77,8 +77,8 @@
7777
end
7878

7979
before do
80-
allow(Rugged::Commit).to receive(:extract_signature)
81-
.with(Rugged::Repository, commit_sha)
80+
allow(Gitlab::Git::Commit).to receive(:extract_signature)
81+
.with(Gitlab::Git::Repository, commit_sha)
8282
.and_return(
8383
[
8484
GpgHelpers::User3.signed_commit_signature,
@@ -116,8 +116,8 @@
116116
end
117117

118118
before do
119-
allow(Rugged::Commit).to receive(:extract_signature)
120-
.with(Rugged::Repository, commit_sha)
119+
allow(Gitlab::Git::Commit).to receive(:extract_signature)
120+
.with(Gitlab::Git::Repository, commit_sha)
121121
.and_return(
122122
[
123123
GpgHelpers::User1.signed_commit_signature,
@@ -151,8 +151,8 @@
151151
end
152152

153153
before do
154-
allow(Rugged::Commit).to receive(:extract_signature)
155-
.with(Rugged::Repository, commit_sha)
154+
allow(Gitlab::Git::Commit).to receive(:extract_signature)
155+
.with(Gitlab::Git::Repository, commit_sha)
156156
.and_return(
157157
[
158158
GpgHelpers::User1.signed_commit_signature,
@@ -187,8 +187,8 @@
187187
end
188188

189189
before do
190-
allow(Rugged::Commit).to receive(:extract_signature)
191-
.with(Rugged::Repository, commit_sha)
190+
allow(Gitlab::Git::Commit).to receive(:extract_signature)
191+
.with(Gitlab::Git::Repository, commit_sha)
192192
.and_return(
193193
[
194194
GpgHelpers::User1.signed_commit_signature,
@@ -217,8 +217,8 @@
217217
let!(:commit) { create :commit, project: project, sha: commit_sha }
218218

219219
before do
220-
allow(Rugged::Commit).to receive(:extract_signature)
221-
.with(Rugged::Repository, commit_sha)
220+
allow(Gitlab::Git::Commit).to receive(:extract_signature)
221+
.with(Gitlab::Git::Repository, commit_sha)
222222
.and_return(
223223
[
224224
GpgHelpers::User1.signed_commit_signature,

spec/lib/gitlab/gpg/invalid_gpg_signature_updater_spec.rb

+2-2
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@
2626
before do
2727
allow_any_instance_of(Project).to receive(:commit).and_return(commit)
2828

29-
allow(Rugged::Commit).to receive(:extract_signature)
30-
.with(Rugged::Repository, commit_sha)
29+
allow(Gitlab::Git::Commit).to receive(:extract_signature)
30+
.with(Gitlab::Git::Repository, commit_sha)
3131
.and_return(signature)
3232
end
3333

0 commit comments

Comments
 (0)