summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/controllers/profiles/gpg_keys_controller.rb10
-rw-r--r--app/models/gpg_key.rb11
-rw-r--r--app/views/profiles/gpg_keys/_key.html.haml8
-rw-r--r--config/routes/profile.rb6
-rw-r--r--doc/workflow/gpg_signed_commits/index.md27
-rw-r--r--spec/features/profiles/gpg_keys_spec.rb16
-rw-r--r--spec/models/gpg_key_spec.rb27
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