diff options
Diffstat (limited to 'spec/models/key_spec.rb')
-rw-r--r-- | spec/models/key_spec.rb | 152 |
1 files changed, 108 insertions, 44 deletions
diff --git a/spec/models/key_spec.rb b/spec/models/key_spec.rb index f27920f9feb..06d26ef89f1 100644 --- a/spec/models/key_spec.rb +++ b/spec/models/key_spec.rb @@ -1,8 +1,6 @@ require 'spec_helper' -describe Key, models: true do - include EmailHelpers - +describe Key, :mailer do describe "Associations" do it { is_expected.to belong_to(:user) } end @@ -13,8 +11,13 @@ describe Key, models: true do it { is_expected.to validate_presence_of(:key) } it { is_expected.to validate_length_of(:key).is_at_most(5000) } - it { is_expected.to allow_value('ssh-foo').for(:key) } - it { is_expected.to allow_value('ecdsa-foo').for(:key) } + it { is_expected.to allow_value(attributes_for(:rsa_key_2048)[:key]).for(:key) } + it { is_expected.to allow_value(attributes_for(:rsa_key_4096)[:key]).for(:key) } + it { is_expected.to allow_value(attributes_for(:rsa_key_5120)[:key]).for(:key) } + it { is_expected.to allow_value(attributes_for(:rsa_key_8192)[:key]).for(:key) } + it { is_expected.to allow_value(attributes_for(:dsa_key_2048)[:key]).for(:key) } + it { is_expected.to allow_value(attributes_for(:ecdsa_key_256)[:key]).for(:key) } + it { is_expected.to allow_value(attributes_for(:ed25519_key_256)[:key]).for(:key) } it { is_expected.not_to allow_value('foo-bar').for(:key) } end @@ -30,30 +33,17 @@ describe Key, models: true do end describe "#update_last_used_at" do - let(:key) { create(:key) } - - context 'when key was not updated during the last day' do - before do - allow_any_instance_of(Gitlab::ExclusiveLease).to receive(:try_obtain) - .and_return('000000') - end - - it 'enqueues a UseKeyWorker job' do - expect(UseKeyWorker).to receive(:perform_async).with(key.id) - key.update_last_used_at - end - end + it 'updates the last used timestamp' do + key = build(:key) + service = double(:service) + + expect(Keys::LastUsedService).to receive(:new) + .with(key) + .and_return(service) - context 'when key was updated during the last day' do - before do - allow_any_instance_of(Gitlab::ExclusiveLease).to receive(:try_obtain) - .and_return(false) - end + expect(service).to receive(:execute) - it 'does not enqueue a UseKeyWorker job' do - expect(UseKeyWorker).not_to receive(:perform_async) - key.update_last_used_at - end + key.update_last_used_at end end end @@ -85,23 +75,76 @@ describe Key, models: true do expect(build(:key)).to be_valid end - it 'rejects an unfingerprintable key that contains a space' do - key = build(:key) + it 'rejects the unfingerprintable key (not a key)' do + expect(build(:key, key: 'ssh-rsa an-invalid-key==')).not_to be_valid + end + + where(:factory, :chars, :expected_sections) do + [ + [:key, ["\n", "\r\n"], 3], + [:key, [' ', ' '], 3], + [:key_without_comment, [' ', ' '], 2] + ] + end - # Not always the middle, but close enough - key.key = key.key[0..100] + ' ' + key.key[101..-1] + with_them do + let!(:key) { create(factory) } + let!(:original_fingerprint) { key.fingerprint } - expect(key).not_to be_valid + it 'accepts a key with blank space characters after stripping them' do + modified_key = key.key.insert(100, chars.first).insert(40, chars.last) + _, content = modified_key.split + + key.update!(key: modified_key) + + expect(key).to be_valid + expect(key.key.split.size).to eq(expected_sections) + + expect(content).not_to match(/\s/) + expect(original_fingerprint).to eq(key.fingerprint) + end end + end - it 'rejects the unfingerprintable key (not a key)' do - expect(build(:key, key: 'ssh-rsa an-invalid-key==')).not_to be_valid + context 'validate it meets key restrictions' do + where(:factory, :minimum, :result) do + forbidden = ApplicationSetting::FORBIDDEN_KEY_VALUE + + [ + [:rsa_key_2048, 0, true], + [:dsa_key_2048, 0, true], + [:ecdsa_key_256, 0, true], + [:ed25519_key_256, 0, true], + + [:rsa_key_2048, 1024, true], + [:rsa_key_2048, 2048, true], + [:rsa_key_2048, 4096, false], + + [:dsa_key_2048, 1024, true], + [:dsa_key_2048, 2048, true], + [:dsa_key_2048, 4096, false], + + [:ecdsa_key_256, 256, true], + [:ecdsa_key_256, 384, false], + + [:ed25519_key_256, 256, true], + [:ed25519_key_256, 384, false], + + [:rsa_key_2048, forbidden, false], + [:dsa_key_2048, forbidden, false], + [:ecdsa_key_256, forbidden, false], + [:ed25519_key_256, forbidden, false] + ] end - it 'rejects the multiple line key' do - key = build(:key) - key.key.tr!(' ', "\n") - expect(key).not_to be_valid + with_them do + subject(:key) { build(factory) } + + before do + stub_application_setting("#{key.public_key.type}_key_restriction" => minimum) + end + + it { expect(key.valid?).to eq(result) } end end @@ -127,17 +170,38 @@ describe Key, models: true do it 'strips white spaces' do expect(described_class.new(key: " #{valid_key} ").key).to eq(valid_key) end + + it 'invalidates the public_key attribute' do + key = build(:key) + + original = key.public_key + key.key = valid_key + + expect(original.key_text).not_to be_nil + expect(key.public_key.key_text).to eq(valid_key) + end end - describe 'notification' do - let(:user) { create(:user) } + describe '#refresh_user_cache', :use_clean_rails_memory_store_caching do + context 'when the key belongs to a user' do + it 'refreshes the keys count cache for the user' do + expect_any_instance_of(Users::KeysCountService) + .to receive(:refresh_cache) + .and_call_original - it 'sends a notification' do - perform_enqueued_jobs do - create(:key, user: user) + key = create(:personal_key) + + expect(Users::KeysCountService.new(key.user).count).to eq(1) end + end - should_email(user) + context 'when the key does not belong to a user' do + it 'does nothing' do + expect_any_instance_of(Users::KeysCountService) + .not_to receive(:refresh_cache) + + create(:key) + end end end end |