diff options
-rw-r--r-- | app/assets/javascripts/commons/bootstrap.js | 1 | ||||
-rw-r--r-- | app/assets/javascripts/main.js | 6 | ||||
-rw-r--r-- | app/assets/stylesheets/pages/commits.scss | 43 | ||||
-rw-r--r-- | app/helpers/commits_helper.rb | 78 | ||||
-rw-r--r-- | app/views/projects/commit/_signature.html.haml | 4 | ||||
-rw-r--r-- | spec/features/commits_spec.rb | 25 |
6 files changed, 154 insertions, 3 deletions
diff --git a/app/assets/javascripts/commons/bootstrap.js b/app/assets/javascripts/commons/bootstrap.js index 36bfe457be9..510bedbf641 100644 --- a/app/assets/javascripts/commons/bootstrap.js +++ b/app/assets/javascripts/commons/bootstrap.js @@ -8,6 +8,7 @@ import 'bootstrap-sass/assets/javascripts/bootstrap/modal'; import 'bootstrap-sass/assets/javascripts/bootstrap/tab'; import 'bootstrap-sass/assets/javascripts/bootstrap/transition'; import 'bootstrap-sass/assets/javascripts/bootstrap/tooltip'; +import 'bootstrap-sass/assets/javascripts/bootstrap/popover'; // custom jQuery functions $.fn.extend({ diff --git a/app/assets/javascripts/main.js b/app/assets/javascripts/main.js index e96d51de838..ecf7a677c99 100644 --- a/app/assets/javascripts/main.js +++ b/app/assets/javascripts/main.js @@ -159,6 +159,8 @@ document.addEventListener('beforeunload', function () { $(document).off('scroll'); // Close any open tooltips $('.has-tooltip, [data-toggle="tooltip"]').tooltip('destroy'); + // Close any open popover + $('[data-toggle="popover"]').popover('destroy'); }); window.addEventListener('hashchange', gl.utils.handleLocationHash); @@ -247,6 +249,10 @@ $(function () { return $(el).data('placement') || 'bottom'; } }); + // Initialize popovers + $body.popover({ + selector: '[data-toggle="popover"]' + }); $('.trigger-submit').on('change', function () { return $(this).parents('form').submit(); // Form submitter diff --git a/app/assets/stylesheets/pages/commits.scss b/app/assets/stylesheets/pages/commits.scss index fd0871ec0b8..54f6156ad8f 100644 --- a/app/assets/stylesheets/pages/commits.scss +++ b/app/assets/stylesheets/pages/commits.scss @@ -283,3 +283,46 @@ color: $gl-text-color; } } + +.gpg-badge { + &.valid { + color: $brand-success; + } + + &.invalid { + color: $gray; + } +} + +.gpg-badge-popover-title { + font-weight: normal; +} + +.gpg-badge-popover-icon { + float: left; + font-size: 35px; + line-height: 35px; + width: 32px; + margin-right: $btn-side-margin; + + &.valid { + color: $brand-success; + } + + &.invalid { + color: $gray; + } +} + +.gpg-badge-popover-avatar { + float: left; + margin-bottom: $gl-padding; + + .avatar { + margin-left: 0; + } +} + +.gpg-badge-popover-username { + font-weight: bold; +} diff --git a/app/helpers/commits_helper.rb b/app/helpers/commits_helper.rb index d08e346d605..34ba5694288 100644 --- a/app/helpers/commits_helper.rb +++ b/app/helpers/commits_helper.rb @@ -212,4 +212,82 @@ module CommitsHelper [commits, 0] end end + + def commit_gpg_signature_badge(signature) + if signature.valid_signature? + commit_gpg_valid_signature_badge(signature) + else + commit_gpg_invalid_signature_badge(signature) + end + end + + def commit_gpg_valid_signature_badge(signature) + title = capture do + concat content_tag('i', '', class: 'fa fa-check-circle gpg-badge-popover-icon valid', 'aria-hidden' => 'true') + concat 'This commit was signed with a verified signature.' + end + + content = capture do + concat( + content_tag(:div, class: 'gpg-badge-popover-avatar') do + user_avatar(user: signature.gpg_key.user, size: 32) + end + ) + + concat( + content_tag(:div, class: 'gpg-badge-popover-username') do + signature.gpg_key.user.username + end + ) + + concat( + content_tag(:div) do + signature.gpg_key.user.name + end + ) + end + + commit_gpg_signature_badge_with(signature, label: 'Verified', title: title, content: content, css_classes: ['valid']) + end + + def commit_gpg_invalid_signature_badge(signature) + title = capture do + concat content_tag('i', '', class: 'fa fa-question-circle gpg-badge-popover-icon invalid', 'aria-hidden' => 'true') + concat 'This commit was signed with an unverified signature.' + end + commit_gpg_signature_badge_with(signature, label: 'Unverified', title: title, css_classes: ['invalid']) + end + + def commit_gpg_signature_badge_with(signature, label:, title: '', content: '', css_classes: []) + css_classes = %w(btn btn-xs gpg-badge) + css_classes + + content = capture do + concat( + content_tag(:div, class: 'clearfix') do + content + end + ) + + concat "GPG key ID: #{signature.gpg_key_primary_keyid}" + end + + title = capture do + content_tag 'span', class: 'gpg-badge-popover-title' do + title + end + end + + data = { + toggle: 'popover', + html: 'true', + placement: 'auto bottom', + trigger: 'focus', + title: title, + content: content + } + + content_tag :button, class: css_classes, data: data do + label + end + end end diff --git a/app/views/projects/commit/_signature.html.haml b/app/views/projects/commit/_signature.html.haml index 48665ede6eb..00120a665c5 100644 --- a/app/views/projects/commit/_signature.html.haml +++ b/app/views/projects/commit/_signature.html.haml @@ -1,4 +1,2 @@ - if signature - %a.btn.disabled.btn-xs{ class: ('btn-success' if signature.valid_signature?) } - %i.fa.fa-key{ class: ('fa-inverse' if signature.valid_signature?) } - = signature.valid_signature? ? 'Verified' : 'Unverified' + = commit_gpg_signature_badge(signature) diff --git a/spec/features/commits_spec.rb b/spec/features/commits_spec.rb index 7635e87e838..236e3089c6c 100644 --- a/spec/features/commits_spec.rb +++ b/spec/features/commits_spec.rb @@ -275,5 +275,30 @@ describe 'Commits' do expect(page).to have_content 'Verified' end end + + it 'shows popover badges', :js do + user = create :user, email: GpgHelpers::User1.emails.first, username: 'nannie.bernhard', name: 'Nannie Bernhard' + project.team << [user, :master] + Sidekiq::Testing.inline! do + create :gpg_key, key: GpgHelpers::User1.public_key, user: user + end + + login_with(user) + visit namespace_project_commits_path(project.namespace, project, :master) + + click_on 'Verified' + within '.popover' do + expect(page).to have_content 'This commit was signed with a verified signature.' + expect(page).to have_content 'nannie.bernhard' + expect(page).to have_content 'Nannie Bernhard' + expect(page).to have_content "GPG key ID: #{GpgHelpers::User1.primary_keyid}" + end + + click_on 'Unverified', match: :first + within '.popover' do + expect(page).to have_content 'This commit was signed with an unverified signature.' + expect(page).to have_content "GPG key ID: #{GpgHelpers::User2.primary_keyid}" + end + end end end |