From 87c0fd34557463528a552986a42f4ebb52d3bd56 Mon Sep 17 00:00:00 2001 From: Alexis Reigel Date: Wed, 22 Feb 2017 18:36:25 +0100 Subject: add / remove gpg keys to / from system keychain --- app/models/gpg_key.rb | 10 ++++++++++ lib/gitlab/gpg.rb | 8 ++++++++ spec/lib/gitlab/gpg_spec.rb | 20 +++++++++++++++++++- spec/models/gpg_key_spec.rb | 24 +++++++++++++++++++++--- spec/support/gpg_helpers.rb | 2 +- 5 files changed, 59 insertions(+), 5 deletions(-) diff --git a/app/models/gpg_key.rb b/app/models/gpg_key.rb index aa0e8883a47..a9f1400650c 100644 --- a/app/models/gpg_key.rb +++ b/app/models/gpg_key.rb @@ -19,6 +19,8 @@ class GpgKey < ActiveRecord::Base unless: -> { errors.has_key?(:key) } before_validation :extract_fingerprint + after_create :add_to_keychain + after_destroy :remove_from_keychain def key=(value) value.strip! unless value.blank? @@ -37,4 +39,12 @@ class GpgKey < ActiveRecord::Base # only allows one key self.fingerprint = Gitlab::Gpg.fingerprints_from_key(key).first end + + def add_to_keychain + Gitlab::Gpg.add_to_keychain(key) + end + + def remove_from_keychain + Gitlab::Gpg.remove_from_keychain(fingerprint) + end end diff --git a/lib/gitlab/gpg.rb b/lib/gitlab/gpg.rb index 373ef79ab85..64f18d00e46 100644 --- a/lib/gitlab/gpg.rb +++ b/lib/gitlab/gpg.rb @@ -12,6 +12,14 @@ module Gitlab end end + def add_to_keychain(key) + GPGME::Key.import(key) + end + + def remove_from_keychain(fingerprint) + GPGME::Key.get(fingerprint).delete! + end + def using_tmp_keychain Dir.mktmpdir do |dir| @original_dirs ||= [GPGME::Engine.dirinfo('homedir')] diff --git a/spec/lib/gitlab/gpg_spec.rb b/spec/lib/gitlab/gpg_spec.rb index a59302e6738..2f779492c24 100644 --- a/spec/lib/gitlab/gpg_spec.rb +++ b/spec/lib/gitlab/gpg_spec.rb @@ -15,6 +15,24 @@ describe Gitlab::Gpg do end end - describe '.add_to_keychain' do + describe '.add_to_keychain', :gpg do + it 'stores the key in the keychain' do + expect(GPGME::Key.find(:public, '4F4840A503964251CF7D7F5DC728AF10972E97C0')).to eq [] + + Gitlab::Gpg.add_to_keychain(GpgHelpers.public_key) + + expect(GPGME::Key.find(:public, '4F4840A503964251CF7D7F5DC728AF10972E97C0')).not_to eq [] + end + end + + describe '.remove_from_keychain', :gpg do + it 'removes the key from the keychain' do + Gitlab::Gpg.add_to_keychain(GpgHelpers.public_key) + expect(GPGME::Key.find(:public, '4F4840A503964251CF7D7F5DC728AF10972E97C0')).not_to eq [] + + Gitlab::Gpg.remove_from_keychain('4F4840A503964251CF7D7F5DC728AF10972E97C0') + + expect(GPGME::Key.find(:public, '4F4840A503964251CF7D7F5DC728AF10972E97C0')).to eq [] + end end end diff --git a/spec/models/gpg_key_spec.rb b/spec/models/gpg_key_spec.rb index 1c5dd95ba65..facdf91550f 100644 --- a/spec/models/gpg_key_spec.rb +++ b/spec/models/gpg_key_spec.rb @@ -13,14 +13,32 @@ describe GpgKey do it { is_expected.not_to allow_value('BEGIN PGP').for(:key) } end - context 'callbacks' do + context 'callbacks', :gpg do describe 'extract_fingerprint' do - it 'extracts the fingerprint from the gpg key', :gpg do + it 'extracts the fingerprint from the gpg key' do gpg_key = described_class.new(key: GpgHelpers.public_key) gpg_key.valid? expect(gpg_key.fingerprint).to eq '4F4840A503964251CF7D7F5DC728AF10972E97C0' end end + + describe 'add_to_keychain' do + it 'calls add_to_keychain after create' do + expect(Gitlab::Gpg).to receive(:add_to_keychain).with(GpgHelpers.public_key) + create :gpg_key + end + end + + describe 'remove_from_keychain' do + it 'calls remove_from_keychain after destroy' do + allow(Gitlab::Gpg).to receive :add_to_keychain + gpg_key = create :gpg_key + + expect(Gitlab::Gpg).to receive(:remove_from_keychain).with('4F4840A503964251CF7D7F5DC728AF10972E97C0') + + gpg_key.destroy! + end + end end describe '#key=' do @@ -37,7 +55,7 @@ describe GpgKey do end end - describe '#emails' do + describe '#emails', :gpg do it 'returns the emails from the gpg key' do gpg_key = create :gpg_key diff --git a/spec/support/gpg_helpers.rb b/spec/support/gpg_helpers.rb index 3b50d831b00..2f440488546 100644 --- a/spec/support/gpg_helpers.rb +++ b/spec/support/gpg_helpers.rb @@ -29,7 +29,7 @@ module GpgHelpers end def public_key - <<~PUBLICKEY + <<~PUBLICKEY.strip -----BEGIN PGP PUBLIC KEY BLOCK----- Version: GnuPG v1 -- cgit v1.2.1