2017-09-10 17:25:29 +05:30
|
|
|
require 'rails_helper'
|
|
|
|
|
|
|
|
describe Gitlab::Gpg do
|
|
|
|
describe '.fingerprints_from_key' do
|
|
|
|
before do
|
|
|
|
# make sure that each method is using the temporary keychain
|
|
|
|
expect(described_class).to receive(:using_tmp_keychain).and_call_original
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns CurrentKeyChain.fingerprints_from_key' do
|
|
|
|
expect(Gitlab::Gpg::CurrentKeyChain).to receive(:fingerprints_from_key).with(GpgHelpers::User1.public_key)
|
|
|
|
|
|
|
|
described_class.fingerprints_from_key(GpgHelpers::User1.public_key)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe '.primary_keyids_from_key' do
|
|
|
|
it 'returns the keyid' do
|
|
|
|
expect(
|
|
|
|
described_class.primary_keyids_from_key(GpgHelpers::User1.public_key)
|
|
|
|
).to eq [GpgHelpers::User1.primary_keyid]
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns an empty array when the key is invalid' do
|
|
|
|
expect(
|
|
|
|
described_class.primary_keyids_from_key('bogus')
|
|
|
|
).to eq []
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2018-03-17 18:26:18 +05:30
|
|
|
describe '.subkeys_from_key' do
|
|
|
|
it 'returns the subkeys by primary key' do
|
|
|
|
all_subkeys = described_class.subkeys_from_key(GpgHelpers::User1.public_key)
|
|
|
|
subkeys = all_subkeys[GpgHelpers::User1.primary_keyid]
|
|
|
|
|
|
|
|
expect(subkeys).to be_present
|
|
|
|
expect(subkeys.first[:keyid]).to be_present
|
|
|
|
expect(subkeys.first[:fingerprint]).to be_present
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns an empty array when there are not subkeys' do
|
|
|
|
all_subkeys = described_class.subkeys_from_key(GpgHelpers::User4.public_key)
|
|
|
|
|
|
|
|
expect(all_subkeys[GpgHelpers::User4.primary_keyid]).to be_empty
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2017-09-10 17:25:29 +05:30
|
|
|
describe '.user_infos_from_key' do
|
|
|
|
it 'returns the names and emails' do
|
|
|
|
user_infos = described_class.user_infos_from_key(GpgHelpers::User1.public_key)
|
|
|
|
expect(user_infos).to eq([{
|
|
|
|
name: GpgHelpers::User1.names.first,
|
|
|
|
email: GpgHelpers::User1.emails.first
|
|
|
|
}])
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns an empty array when the key is invalid' do
|
|
|
|
expect(
|
|
|
|
described_class.user_infos_from_key('bogus')
|
|
|
|
).to eq []
|
|
|
|
end
|
2018-03-17 18:26:18 +05:30
|
|
|
|
|
|
|
it 'downcases the email' do
|
|
|
|
public_key = double(:key)
|
|
|
|
fingerprints = double(:fingerprints)
|
|
|
|
uid = double(:uid, name: 'Nannie Bernhard', email: 'NANNIE.BERNHARD@EXAMPLE.COM')
|
|
|
|
raw_key = double(:raw_key, uids: [uid])
|
|
|
|
allow(Gitlab::Gpg::CurrentKeyChain).to receive(:fingerprints_from_key).with(public_key).and_return(fingerprints)
|
|
|
|
allow(GPGME::Key).to receive(:find).with(:public, anything).and_return([raw_key])
|
|
|
|
|
|
|
|
user_infos = described_class.user_infos_from_key(public_key)
|
|
|
|
expect(user_infos).to eq([{
|
|
|
|
name: 'Nannie Bernhard',
|
|
|
|
email: 'nannie.bernhard@example.com'
|
|
|
|
}])
|
|
|
|
end
|
2018-11-08 19:23:39 +05:30
|
|
|
|
|
|
|
it 'rejects non UTF-8 names and addresses' do
|
|
|
|
public_key = double(:key)
|
|
|
|
fingerprints = double(:fingerprints)
|
|
|
|
email = "\xEEch@test.com".force_encoding('ASCII-8BIT')
|
|
|
|
uid = double(:uid, name: 'Test User', email: email)
|
|
|
|
raw_key = double(:raw_key, uids: [uid])
|
|
|
|
allow(Gitlab::Gpg::CurrentKeyChain).to receive(:fingerprints_from_key).with(public_key).and_return(fingerprints)
|
|
|
|
allow(GPGME::Key).to receive(:find).with(:public, anything).and_return([raw_key])
|
|
|
|
|
|
|
|
user_infos = described_class.user_infos_from_key(public_key)
|
|
|
|
expect(user_infos).to eq([])
|
|
|
|
end
|
2017-09-10 17:25:29 +05:30
|
|
|
end
|
|
|
|
|
|
|
|
describe '.current_home_dir' do
|
|
|
|
let(:default_home_dir) { GPGME::Engine.dirinfo('homedir') }
|
|
|
|
|
|
|
|
it 'returns the default value when no explicit home dir has been set' do
|
|
|
|
expect(described_class.current_home_dir).to eq default_home_dir
|
|
|
|
end
|
|
|
|
|
2018-12-13 13:39:08 +05:30
|
|
|
it 'returns the explicitly set home dir' do
|
2017-09-10 17:25:29 +05:30
|
|
|
GPGME::Engine.home_dir = '/tmp/gpg'
|
|
|
|
|
|
|
|
expect(described_class.current_home_dir).to eq '/tmp/gpg'
|
|
|
|
|
|
|
|
GPGME::Engine.home_dir = GPGME::Engine.dirinfo('homedir')
|
|
|
|
end
|
|
|
|
|
2018-12-13 13:39:08 +05:30
|
|
|
it 'returns the default value when explicitly setting the home dir to nil' do
|
2017-09-10 17:25:29 +05:30
|
|
|
GPGME::Engine.home_dir = nil
|
|
|
|
|
|
|
|
expect(described_class.current_home_dir).to eq default_home_dir
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe '.using_tmp_keychain' do
|
|
|
|
it "the second thread does not change the first thread's directory" do
|
|
|
|
thread1 = Thread.new do
|
|
|
|
described_class.using_tmp_keychain do
|
|
|
|
dir = described_class.current_home_dir
|
|
|
|
sleep 0.1
|
|
|
|
expect(described_class.current_home_dir).to eq dir
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
thread2 = Thread.new do
|
|
|
|
described_class.using_tmp_keychain do
|
|
|
|
sleep 0.2
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
thread1.join
|
|
|
|
thread2.join
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'allows recursive execution in the same thread' do
|
|
|
|
expect do
|
|
|
|
described_class.using_tmp_keychain do
|
|
|
|
described_class.using_tmp_keychain do
|
|
|
|
end
|
|
|
|
end
|
2019-02-13 22:33:31 +05:30
|
|
|
end.not_to raise_error
|
2017-09-10 17:25:29 +05:30
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe Gitlab::Gpg::CurrentKeyChain do
|
|
|
|
around do |example|
|
|
|
|
Gitlab::Gpg.using_tmp_keychain do
|
|
|
|
example.run
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe '.add' do
|
|
|
|
it 'stores the key in the keychain' do
|
|
|
|
expect(GPGME::Key.find(:public, GpgHelpers::User1.fingerprint)).to eq []
|
|
|
|
|
|
|
|
described_class.add(GpgHelpers::User1.public_key)
|
|
|
|
|
|
|
|
keys = GPGME::Key.find(:public, GpgHelpers::User1.fingerprint)
|
|
|
|
expect(keys.count).to eq 1
|
|
|
|
expect(keys.first).to have_attributes(
|
|
|
|
email: GpgHelpers::User1.emails.first,
|
|
|
|
fingerprint: GpgHelpers::User1.fingerprint
|
|
|
|
)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe '.fingerprints_from_key' do
|
|
|
|
it 'returns the fingerprint' do
|
|
|
|
expect(
|
|
|
|
described_class.fingerprints_from_key(GpgHelpers::User1.public_key)
|
|
|
|
).to eq [GpgHelpers::User1.fingerprint]
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns an empty array when the key is invalid' do
|
|
|
|
expect(
|
|
|
|
described_class.fingerprints_from_key('bogus')
|
|
|
|
).to eq []
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|