Commit d7c7061a authored by Sean McGivern's avatar Sean McGivern

Merge branch 'gitaly-commit-signature' into 'master'

Retrieve commit signatures with Gitaly

Closes gitaly#923

See merge request gitlab-org/gitlab-ce!16467
parents 430b3f0e 4d87f3bb
...@@ -13,31 +13,37 @@ class Projects::CommitsController < Projects::ApplicationController ...@@ -13,31 +13,37 @@ class Projects::CommitsController < Projects::ApplicationController
@merge_request = MergeRequestsFinder.new(current_user, project_id: @project.id).execute.opened @merge_request = MergeRequestsFinder.new(current_user, project_id: @project.id).execute.opened
.find_by(source_project: @project, source_branch: @ref, target_branch: @repository.root_ref) .find_by(source_project: @project, source_branch: @ref, target_branch: @repository.root_ref)
respond_to do |format| # https://gitlab.com/gitlab-org/gitaly/issues/931
format.html Gitlab::GitalyClient.allow_n_plus_1_calls do
format.atom { render layout: 'xml.atom' } respond_to do |format|
format.html
format.json do format.atom { render layout: 'xml.atom' }
pager_json(
'projects/commits/_commits', format.json do
@commits.size, pager_json(
project: @project, 'projects/commits/_commits',
ref: @ref) @commits.size,
project: @project,
ref: @ref)
end
end end
end end
end end
def signatures def signatures
respond_to do |format| # https://gitlab.com/gitlab-org/gitaly/issues/931
format.json do Gitlab::GitalyClient.allow_n_plus_1_calls do
render json: { respond_to do |format|
signatures: @commits.select(&:has_signature?).map do |commit| format.json do
{ render json: {
commit_sha: commit.sha, signatures: @commits.select(&:has_signature?).map do |commit|
html: view_to_html_string('projects/commit/_signature', signature: commit.signature) {
} commit_sha: commit.sha,
end html: view_to_html_string('projects/commit/_signature', signature: commit.signature)
} }
end
}
end
end end
end end
end end
......
...@@ -239,6 +239,24 @@ module Gitlab ...@@ -239,6 +239,24 @@ module Gitlab
end end
end end
end end
def extract_signature(repository, commit_id)
repository.gitaly_migrate(:extract_commit_signature) do |is_enabled|
if is_enabled
repository.gitaly_commit_client.extract_signature(commit_id)
else
rugged_extract_signature(repository, commit_id)
end
end
end
def rugged_extract_signature(repository, commit_id)
begin
Rugged::Commit.extract_signature(repository.rugged, commit_id)
rescue Rugged::OdbError
nil
end
end
end end
def initialize(repository, raw_commit, head = nil) def initialize(repository, raw_commit, head = nil)
......
...@@ -282,6 +282,23 @@ module Gitlab ...@@ -282,6 +282,23 @@ module Gitlab
end end
end end
def extract_signature(commit_id)
request = Gitaly::ExtractCommitSignatureRequest.new(repository: @gitaly_repo, commit_id: commit_id)
response = GitalyClient.call(@repository.storage, :commit_service, :extract_commit_signature, request)
signature = ''.b
signed_text = ''.b
response.each do |message|
signature << message.signature
signed_text << message.signed_text
end
return if signature.blank? && signed_text.blank?
[signature, signed_text]
end
private private
def call_commit_diff(request_params, options = {}) def call_commit_diff(request_params, options = {})
......
...@@ -4,12 +4,8 @@ module Gitlab ...@@ -4,12 +4,8 @@ module Gitlab
def initialize(commit) def initialize(commit)
@commit = commit @commit = commit
@signature_text, @signed_text = repo = commit.project.repository.raw_repository
begin @signature_text, @signed_text = Gitlab::Git::Commit.extract_signature(repo, commit.sha)
Rugged::Commit.extract_signature(@commit.project.repository.rugged, @commit.sha)
rescue Rugged::OdbError
nil
end
end end
def has_signature? def has_signature?
......
...@@ -388,6 +388,84 @@ describe Gitlab::Git::Commit, seed_helper: true do ...@@ -388,6 +388,84 @@ describe Gitlab::Git::Commit, seed_helper: true do
end end
end end
end end
describe '.extract_signature' do
subject { described_class.extract_signature(repository, commit_id) }
shared_examples '.extract_signature' do
context 'when the commit is signed' do
let(:commit_id) { '0b4bc9a49b562e85de7cc9e834518ea6828729b9' }
it 'returns signature and signed text' do
signature, signed_text = subject
expected_signature = <<~SIGNATURE
-----BEGIN PGP SIGNATURE-----
Version: GnuPG/MacGPG2 v2.0.22 (Darwin)
Comment: GPGTools - https://gpgtools.org
iQEcBAABCgAGBQJTDvaZAAoJEGJ8X1ifRn8XfvYIAMuB0yrbTGo1BnOSoDfyrjb0
Kw2EyUzvXYL72B63HMdJ+/0tlSDC6zONF3fc+bBD8z+WjQMTbwFNMRbSSy2rKEh+
mdRybOP3xBIMGgEph0/kmWln39nmFQBsPRbZBWoU10VfI/ieJdEOgOphszgryRar
TyS73dLBGE9y9NIININVaNISet9D9QeXFqc761CGjh4YIghvPpi+YihMWapGka6v
hgKhX+hc5rj+7IEE0CXmlbYR8OYvAbAArc5vJD7UTxAY4Z7/l9d6Ydt9GQ25khfy
ANFgltYzlR6evLFmDjssiP/mx/ZMN91AL0ueJ9nNGv411Mu2CUW+tDCaQf35mdc=
=j51i
-----END PGP SIGNATURE-----
SIGNATURE
expect(signature).to eq(expected_signature.chomp)
expect(signature).to be_a_binary_string
expected_signed_text = <<~SIGNED_TEXT
tree 22bfa2fbd217df24731f43ff43a4a0f8db759dae
parent ae73cb07c9eeaf35924a10f713b364d32b2dd34f
author Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com> 1393489561 +0200
committer Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com> 1393489561 +0200
Feature added
Signed-off-by: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
SIGNED_TEXT
expect(signed_text).to eq(expected_signed_text)
expect(signed_text).to be_a_binary_string
end
end
context 'when the commit has no signature' do
let(:commit_id) { '4b4918a572fa86f9771e5ba40fbd48e1eb03e2c6' }
it 'returns nil' do
expect(subject).to be_nil
end
end
context 'when the commit cannot be found' do
let(:commit_id) { Gitlab::Git::BLANK_SHA }
it 'returns nil' do
expect(subject).to be_nil
end
end
context 'when the commit ID is invalid' do
let(:commit_id) { '4b4918a572fa86f9771e5ba40fbd48e' }
it 'raises ArgumentError' do
expect { subject }.to raise_error(ArgumentError)
end
end
end
context 'with gitaly' do
it_behaves_like '.extract_signature'
end
context 'without gitaly', :skip_gitaly_mock do
it_behaves_like '.extract_signature'
end
end
end end
describe '#init_from_rugged' do describe '#init_from_rugged' do
......
...@@ -38,8 +38,8 @@ describe Gitlab::Gpg::Commit do ...@@ -38,8 +38,8 @@ describe Gitlab::Gpg::Commit do
end end
before do before do
allow(Rugged::Commit).to receive(:extract_signature) allow(Gitlab::Git::Commit).to receive(:extract_signature)
.with(Rugged::Repository, commit_sha) .with(Gitlab::Git::Repository, commit_sha)
.and_return( .and_return(
[ [
GpgHelpers::User1.signed_commit_signature, GpgHelpers::User1.signed_commit_signature,
...@@ -77,8 +77,8 @@ describe Gitlab::Gpg::Commit do ...@@ -77,8 +77,8 @@ describe Gitlab::Gpg::Commit do
end end
before do before do
allow(Rugged::Commit).to receive(:extract_signature) allow(Gitlab::Git::Commit).to receive(:extract_signature)
.with(Rugged::Repository, commit_sha) .with(Gitlab::Git::Repository, commit_sha)
.and_return( .and_return(
[ [
GpgHelpers::User3.signed_commit_signature, GpgHelpers::User3.signed_commit_signature,
...@@ -116,8 +116,8 @@ describe Gitlab::Gpg::Commit do ...@@ -116,8 +116,8 @@ describe Gitlab::Gpg::Commit do
end end
before do before do
allow(Rugged::Commit).to receive(:extract_signature) allow(Gitlab::Git::Commit).to receive(:extract_signature)
.with(Rugged::Repository, commit_sha) .with(Gitlab::Git::Repository, commit_sha)
.and_return( .and_return(
[ [
GpgHelpers::User1.signed_commit_signature, GpgHelpers::User1.signed_commit_signature,
...@@ -151,8 +151,8 @@ describe Gitlab::Gpg::Commit do ...@@ -151,8 +151,8 @@ describe Gitlab::Gpg::Commit do
end end
before do before do
allow(Rugged::Commit).to receive(:extract_signature) allow(Gitlab::Git::Commit).to receive(:extract_signature)
.with(Rugged::Repository, commit_sha) .with(Gitlab::Git::Repository, commit_sha)
.and_return( .and_return(
[ [
GpgHelpers::User1.signed_commit_signature, GpgHelpers::User1.signed_commit_signature,
...@@ -187,8 +187,8 @@ describe Gitlab::Gpg::Commit do ...@@ -187,8 +187,8 @@ describe Gitlab::Gpg::Commit do
end end
before do before do
allow(Rugged::Commit).to receive(:extract_signature) allow(Gitlab::Git::Commit).to receive(:extract_signature)
.with(Rugged::Repository, commit_sha) .with(Gitlab::Git::Repository, commit_sha)
.and_return( .and_return(
[ [
GpgHelpers::User1.signed_commit_signature, GpgHelpers::User1.signed_commit_signature,
...@@ -217,8 +217,8 @@ describe Gitlab::Gpg::Commit do ...@@ -217,8 +217,8 @@ describe Gitlab::Gpg::Commit do
let!(:commit) { create :commit, project: project, sha: commit_sha } let!(:commit) { create :commit, project: project, sha: commit_sha }
before do before do
allow(Rugged::Commit).to receive(:extract_signature) allow(Gitlab::Git::Commit).to receive(:extract_signature)
.with(Rugged::Repository, commit_sha) .with(Gitlab::Git::Repository, commit_sha)
.and_return( .and_return(
[ [
GpgHelpers::User1.signed_commit_signature, GpgHelpers::User1.signed_commit_signature,
......
...@@ -26,8 +26,8 @@ RSpec.describe Gitlab::Gpg::InvalidGpgSignatureUpdater do ...@@ -26,8 +26,8 @@ RSpec.describe Gitlab::Gpg::InvalidGpgSignatureUpdater do
before do before do
allow_any_instance_of(Project).to receive(:commit).and_return(commit) allow_any_instance_of(Project).to receive(:commit).and_return(commit)
allow(Rugged::Commit).to receive(:extract_signature) allow(Gitlab::Git::Commit).to receive(:extract_signature)
.with(Rugged::Repository, commit_sha) .with(Gitlab::Git::Repository, commit_sha)
.and_return(signature) .and_return(signature)
end end
......
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