diff --git a/Gemfile b/Gemfile index 43109de1b45148c8d0ab1e3a4c99a1d790a0cb68..93934d03e421f642bce5bc5e1264d3057f774915 100644 --- a/Gemfile +++ b/Gemfile @@ -58,6 +58,9 @@ gem 'validates_hostname', '~> 1.0.6' # Browser detection gem 'browser', '~> 2.2' +# GPG +gem 'gpgme' + # LDAP Auth # GitLab fork with several improvements to original library. For full list of changes # see https://github.com/intridea/omniauth-ldap/compare/master...gitlabhq:master diff --git a/Gemfile.lock b/Gemfile.lock index 6c2ac9368f20f9e05ace4d9d3d6b5facc3b4416d..77e87e2885fa71164d2480a1409ab8503376d34e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -332,6 +332,8 @@ GEM multi_json (~> 1.11) os (~> 0.9) signet (~> 0.7) + gpgme (2.0.13) + mini_portile2 (~> 2.1) grape (0.19.2) activesupport builder @@ -983,6 +985,7 @@ DEPENDENCIES gollum-rugged_adapter (~> 0.4.4) gon (~> 6.1.0) google-api-client (~> 0.8.6) + gpgme grape (~> 0.19.2) grape-entity (~> 0.6.0) grape-route-helpers (~> 2.0.0) diff --git a/app/models/commit.rb b/app/models/commit.rb index 1e19f00106a1b6dba61f0d0cee646aee16d2f984..b22aaa3c4619946d78955ee9a24524899575227c 100644 --- a/app/models/commit.rb +++ b/app/models/commit.rb @@ -234,6 +234,18 @@ class Commit @statuses[ref] = pipelines.latest_status(ref) end + def signature + return @signature if defined?(@signature) + + sig, signed = @raw.extract_signature(project.repository.raw_repository) + if sig && signed + GPGME::Crypto.new.verify(sig, signed_text: signed) do |sign| + @signature = sign + end + end + @signature ||= nil + end + def revert_branch_name "revert-#{short_id}" end diff --git a/app/views/projects/commit/_commit_box.html.haml b/app/views/projects/commit/_commit_box.html.haml index 45109f2c58b55605d10eaca1fd6fb513fd949647..1a0c70ef803533296f83de9f27872f4578dd021b 100644 --- a/app/views/projects/commit/_commit_box.html.haml +++ b/app/views/projects/commit/_commit_box.html.haml @@ -6,6 +6,7 @@ = clipboard_button(text: @commit.id, title: _("Copy commit SHA to clipboard")) %span.hidden-xs authored #{time_ago_with_tooltip(@commit.authored_date)} + = render partial: 'signature', object: @commit.signature %span= s_('ByAuthor|by') = author_avatar(@commit, size: 24) %strong diff --git a/app/views/projects/commit/_signature.html.haml b/app/views/projects/commit/_signature.html.haml new file mode 100644 index 0000000000000000000000000000000000000000..7335b6b9597831990e6060228b0e03b2e8a0973c --- /dev/null +++ b/app/views/projects/commit/_signature.html.haml @@ -0,0 +1,4 @@ +- if signature + %a.btn.disabled.btn-xs{ class: ('btn-success' if signature.valid?) } + %i.fa.fa-key{ class: ('fa-inverse' if signature.valid?) } + = signature.valid? ? 'Verified': 'Unverified' diff --git a/app/views/projects/commits/_commit.html.haml b/app/views/projects/commits/_commit.html.haml index 1033bad0d49e16ebe4e1c490f015808a6f0c3cc5..5f67727514a3b3ae2b13a4b6dd1ccd132eaab344 100644 --- a/app/views/projects/commits/_commit.html.haml +++ b/app/views/projects/commits/_commit.html.haml @@ -39,6 +39,7 @@ .commit-actions.flex-row.hidden-xs - if commit.status(ref) = render_commit_status(commit, ref: ref) + = render partial: 'projects/commit/signature', object: commit.signature = link_to commit.short_id, project_commit_path(project, commit), class: "commit-sha btn btn-transparent" = clipboard_button(text: commit.id, title: _("Copy commit SHA to clipboard")) = link_to_browse_code(project, commit) diff --git a/lib/gitlab/git/commit.rb b/lib/gitlab/git/commit.rb index 09511cc6504a0c30da0670ddd41d7a8e5ce3539c..d19f55c423bd3675cdcecbc19f28a1b1bb50afe4 100644 --- a/lib/gitlab/git/commit.rb +++ b/lib/gitlab/git/commit.rb @@ -319,6 +319,10 @@ module Gitlab end end + def extract_signature(repo) + Rugged::Commit.extract_signature(repo.rugged, sha) + end + def stats Gitlab::Git::CommitStats.new(self) end