diff options
-rw-r--r-- | app/controllers/profiles/gpg_keys_controller.rb | 10 | ||||
-rw-r--r-- | app/models/gpg_key.rb | 11 | ||||
-rw-r--r-- | app/views/profiles/gpg_keys/_key.html.haml | 8 | ||||
-rw-r--r-- | config/routes/profile.rb | 6 | ||||
-rw-r--r-- | doc/workflow/gpg_signed_commits/index.md | 27 | ||||
-rw-r--r-- | spec/features/profiles/gpg_keys_spec.rb | 16 | ||||
-rw-r--r-- | spec/models/gpg_key_spec.rb | 27 |
7 files changed, 102 insertions, 3 deletions
diff --git a/app/controllers/profiles/gpg_keys_controller.rb b/app/controllers/profiles/gpg_keys_controller.rb index b04c14a6993..3e75247769d 100644 --- a/app/controllers/profiles/gpg_keys_controller.rb +++ b/app/controllers/profiles/gpg_keys_controller.rb @@ -25,6 +25,16 @@ class Profiles::GpgKeysController < Profiles::ApplicationController end end + def revoke + @gpp_key = current_user.gpg_keys.find(params[:id]) + @gpp_key.revoke + + respond_to do |format| + format.html { redirect_to profile_gpg_keys_url, status: 302 } + format.js { head :ok } + end + end + private def gpg_key_params diff --git a/app/models/gpg_key.rb b/app/models/gpg_key.rb index 050245bd502..1977023536e 100644 --- a/app/models/gpg_key.rb +++ b/app/models/gpg_key.rb @@ -58,6 +58,17 @@ class GpgKey < ActiveRecord::Base InvalidGpgSignatureUpdateWorker.perform_async(self.id) end + def revoke + GpgSignature.where(gpg_key: self, valid_signature: true).find_each do |gpg_signature| + gpg_signature.update_attributes!( + gpg_key: nil, + valid_signature: false + ) + end + + destroy + end + private def extract_fingerprint diff --git a/app/views/profiles/gpg_keys/_key.html.haml b/app/views/profiles/gpg_keys/_key.html.haml index b4b9aa07190..86e2510d22f 100644 --- a/app/views/profiles/gpg_keys/_key.html.haml +++ b/app/views/profiles/gpg_keys/_key.html.haml @@ -3,13 +3,17 @@ = icon 'key', class: "settings-list-icon hidden-xs" .key-list-item-info - key.emails_with_verified_status.map do |email, verified| + = email = verified_email_badge(email, verified) .description - = key.fingerprint + %code= key.fingerprint .pull-right %span.key-created-at created #{time_ago_with_tooltip(key.created_at)} - = link_to profile_gpg_key_path(key), data: { confirm: 'Are you sure?' }, method: :delete, class: "btn btn-transparent prepend-left-10" do + = link_to profile_gpg_key_path(key), data: { confirm: 'Are you sure? Removing this GPG key does not affect already signed commits.' }, method: :delete, class: "btn btn-danger prepend-left-10" do %span.sr-only Remove = icon('trash') + = link_to revoke_profile_gpg_key_path(key), data: { confirm: 'Are you sure? All commits that were signed with this GPG key will be unverified.' }, method: :put, class: "btn btn-danger prepend-left-10" do + %span.sr-only Revoke + Revoke diff --git a/config/routes/profile.rb b/config/routes/profile.rb index 00388b9c0cd..3e4e6111ab8 100644 --- a/config/routes/profile.rb +++ b/config/routes/profile.rb @@ -23,7 +23,11 @@ resource :profile, only: [:show, :update] do end resource :preferences, only: [:show, :update] resources :keys, only: [:index, :show, :create, :destroy] - resources :gpg_keys, only: [:index, :create, :destroy] + resources :gpg_keys, only: [:index, :create, :destroy] do + member do + put :revoke + end + end resources :emails, only: [:index, :create, :destroy] resources :chat_names, only: [:index, :new, :create, :destroy] do collection do diff --git a/doc/workflow/gpg_signed_commits/index.md b/doc/workflow/gpg_signed_commits/index.md index f7f5492c35a..7d5762d2b9d 100644 --- a/doc/workflow/gpg_signed_commits/index.md +++ b/doc/workflow/gpg_signed_commits/index.md @@ -42,6 +42,33 @@ For a signature to be verified two prerequisites need to be met: Once you add a key, you cannot edit it, only remove it. In case the paste didn't work, you will have to remove the offending key and re-add it. +## Remove a GPG key + +1. On the upper right corner, click on your avatar and go to your **Settings**. + +1. Navigate to the **GPG keys** tab. + +1. Click on the trash icon besides the GPG key you want to delete. + +>**Note:** +Removing a key **does not unverify** already signed commits. Commits that were +verified by using this key will stay verified. Only unpushed commits will stay +unverified once you remove this key. + +## Revoke a GPG key + +1. On the upper right corner, click on your avatar and go to your **Settings**. + +1. Navigate to the **GPG keys** tab. + +1. Click on **Revoke** besides the GPG key you want to delete. + +>**Note:** +Revoking a key **unverifies** already signed commits. Commits that were +verified by using this key will change to an unverified state. Future commits +will also stay unverified once you revoke this key. This action should be used +in case your key has been compromised. + ## Verifying commits 1. Within a project navigate to the **Commits** tag. Signed commits will show a diff --git a/spec/features/profiles/gpg_keys_spec.rb b/spec/features/profiles/gpg_keys_spec.rb index 350126523b0..6edc482b47e 100644 --- a/spec/features/profiles/gpg_keys_spec.rb +++ b/spec/features/profiles/gpg_keys_spec.rb @@ -39,4 +39,20 @@ feature 'Profile > GPG Keys' do expect(page).to have_content('Your GPG keys (0)') end + + scenario 'User revokes a key via the key index' do + gpg_key = create :gpg_key, user: user, key: GpgHelpers::User2.public_key + gpg_signature = create :gpg_signature, gpg_key: gpg_key, valid_signature: true + + visit profile_gpg_keys_path + + click_link('Revoke') + + expect(page).to have_content('Your GPG keys (0)') + + expect(gpg_signature.reload).to have_attributes( + valid_signature: false, + gpg_key: nil + ) + end end diff --git a/spec/models/gpg_key_spec.rb b/spec/models/gpg_key_spec.rb index ffbf8760e86..ddd0bbfb9ba 100644 --- a/spec/models/gpg_key_spec.rb +++ b/spec/models/gpg_key_spec.rb @@ -95,4 +95,31 @@ describe GpgKey do should_email(user) end end + + describe '#revoke' do + it 'invalidates all associated gpg signatures and destroys the key' do + gpg_key = create :gpg_key + gpg_signature = create :gpg_signature, valid_signature: true, gpg_key: gpg_key + + unrelated_gpg_key = create :gpg_key, key: GpgHelpers::User2.public_key + unrelated_gpg_signature = create :gpg_signature, valid_signature: true, gpg_key: unrelated_gpg_key + + gpg_key.revoke + + expect(gpg_signature.reload).to have_attributes( + valid_signature: false, + gpg_key: nil + ) + + expect(gpg_key.destroyed?).to be true + + # unrelated signature is left untouched + expect(unrelated_gpg_signature.reload).to have_attributes( + valid_signature: true, + gpg_key: unrelated_gpg_key + ) + + expect(unrelated_gpg_key.destroyed?).to be false + end + end end |