mirror of
https://github.com/zammad/zammad
synced 2026-05-24 09:48:36 +00:00
306 lines
10 KiB
Ruby
306 lines
10 KiB
Ruby
# Copyright (C) 2012-2026 Zammad Foundation, https://zammad-foundation.org/
|
|
|
|
require 'rails_helper'
|
|
|
|
RSpec.describe PGPKey, type: :model do
|
|
let(:user) { create(:admin) }
|
|
|
|
describe '#create' do
|
|
let(:fixture) { 'zammad@localhost' }
|
|
let(:key) { Rails.root.join("spec/fixtures/files/pgp/#{fixture}.asc").read }
|
|
let(:fingerprint) { Rails.root.join("spec/fixtures/files/pgp/#{fixture}.fingerprint").read }
|
|
let(:created_at) { DateTime.parse(Rails.root.join("spec/fixtures/files/pgp/#{fixture}.created_at").read) }
|
|
let(:expires_at) { DateTime.parse(Rails.root.join("spec/fixtures/files/pgp/#{fixture}.expires_at").read) }
|
|
let(:passphrase) { Rails.root.join("spec/fixtures/files/pgp/#{fixture}.passphrase").read }
|
|
|
|
let(:params) do
|
|
{
|
|
key: key,
|
|
passphrase: passphrase,
|
|
created_by_id: user.id,
|
|
updated_by_id: user.id,
|
|
}
|
|
end
|
|
|
|
shared_examples 'saving the record' do
|
|
it 'saves the record' do
|
|
expect(described_class.create!(params)).to have_attributes(
|
|
name: fixture,
|
|
fingerprint: fingerprint,
|
|
created_at: created_at,
|
|
expires_at: expires_at,
|
|
email_addresses: [fixture],
|
|
secret: true,
|
|
)
|
|
end
|
|
|
|
it 'prevents duplicate imports' do
|
|
expect { 2.times { described_class.create!(params) } }.to raise_error(ActiveRecord::RecordInvalid)
|
|
end
|
|
end
|
|
|
|
it_behaves_like 'saving the record'
|
|
|
|
context 'with a wrong passphrase' do
|
|
let(:passphrase) { 'foobar' }
|
|
|
|
it 'raises an error' do
|
|
expect { described_class.create!(params) }.to raise_error(ActiveRecord::RecordInvalid)
|
|
end
|
|
end
|
|
|
|
context 'with active domain alias feature' do
|
|
shared_examples 'saving the record with expected domain alias' do |expected|
|
|
it "saves the record with expected domain alias: #{expected.inspect}" do
|
|
expect(described_class.create!(extended_params)).to have_attributes(
|
|
name: fixture,
|
|
fingerprint: fingerprint,
|
|
created_at: created_at,
|
|
expires_at: expires_at,
|
|
email_addresses: [fixture],
|
|
secret: true,
|
|
domain_alias: expected
|
|
)
|
|
end
|
|
end
|
|
|
|
let(:extended_params) do
|
|
params.merge(domain_alias: 'zammad.org')
|
|
end
|
|
|
|
it_behaves_like 'saving the record with expected domain alias', '%@zammad.org'
|
|
|
|
context 'without given domain alias' do
|
|
let(:extended_params) do
|
|
params.merge(domain_alias: nil)
|
|
end
|
|
|
|
it_behaves_like 'saving the record with expected domain alias', nil
|
|
end
|
|
|
|
context 'with an empty domain alias' do
|
|
let(:extended_params) do
|
|
params.merge(domain_alias: '')
|
|
end
|
|
|
|
it_behaves_like 'saving the record with expected domain alias', nil
|
|
end
|
|
end
|
|
|
|
describe 'keyfile' do
|
|
let(:key) { File.open(key_path) }
|
|
|
|
context 'with a binary keyfile' do
|
|
let(:key_path) { Rails.root.join('spec/fixtures/files/pgp/zammad@localhost.pgp') }
|
|
|
|
it_behaves_like 'saving the record'
|
|
end
|
|
|
|
context 'with an invalid keyfile' do
|
|
let(:key_path) { Rails.root.join('spec/fixtures/files/upload/hello_world.txt') }
|
|
|
|
it 'raises an error' do
|
|
expect { described_class.create!(params) }.to raise_error(ActiveRecord::RecordInvalid)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
describe '#prepare_email_addresses' do
|
|
let(:pgp_key) { create(:pgp_key) }
|
|
|
|
before do
|
|
pgp_key.update(name: name)
|
|
pgp_key.prepare_email_addresses
|
|
end
|
|
|
|
shared_examples 'saving only email addresses' do |expected|
|
|
it 'saves only email addresses' do
|
|
expect(pgp_key.email_addresses).to eq(expected)
|
|
end
|
|
end
|
|
|
|
context 'with single UID' do
|
|
context 'with real name and email address' do
|
|
let(:name) { 'Zammad Helpdesk <zammad@localhost>' }
|
|
|
|
it_behaves_like 'saving only email addresses', ['zammad@localhost']
|
|
end
|
|
end
|
|
|
|
context 'with multiple UIDs' do
|
|
let(:name) { 'Multi PGP1 <multipgp1@example.com>, Multi PGP2 <multipgp2@example.com>' }
|
|
|
|
it_behaves_like 'saving only email addresses', ['multipgp1@example.com', 'multipgp2@example.com']
|
|
end
|
|
end
|
|
|
|
describe '#email_addresses' do
|
|
let(:pgp_key) { create(:'pgp_key/zammad@localhost') }
|
|
|
|
it 'returns correct email address' do
|
|
expect(pgp_key.email_addresses).to eq(['zammad@localhost'])
|
|
end
|
|
|
|
context 'with multiple UIDs' do
|
|
let(:pgp_key) { create(:'pgp_key/multipgp2@example.com') }
|
|
|
|
it 'returns all associated email addresses' do
|
|
expect(pgp_key.email_addresses).to eq(['multipgp1@example.com', 'multipgp2@example.com'])
|
|
end
|
|
end
|
|
end
|
|
|
|
describe '.for_recipient_email_addresses!' do
|
|
let!(:pgp_key1) { create(:'pgp_key/pgp1@example.com') }
|
|
let!(:pgp_key2) { create(:'pgp_key/pgp2@example.com') }
|
|
let!(:pgp_key3) { create(:'pgp_key/pgp3@example.com') }
|
|
|
|
context 'when all supplied addresses have corresponding keys available' do
|
|
let(:addresses) { %w[pgp1@example.com pgp2@example.com pgp3@example.com] }
|
|
|
|
it 'returns correct keys' do
|
|
expect(described_class.for_recipient_email_addresses!(addresses)).to include(pgp_key1, pgp_key2, pgp_key3)
|
|
end
|
|
end
|
|
|
|
context 'when one of supplied addresses does not have a corresponding key available' do
|
|
let(:addresses) { %w[pgp1@example.com pgp2@example.com pgp3@example.com nonexistentkey@example.com] }
|
|
|
|
it 'raises an error' do
|
|
expect { described_class.for_recipient_email_addresses!(addresses) }.to raise_error(ActiveRecord::RecordNotFound)
|
|
end
|
|
end
|
|
|
|
context 'when none of supplied addresses has a corresponding key available' do
|
|
let(:addresses) { %w[nonexistentkey@example.com anothernonexistentkey@example.com] }
|
|
|
|
it 'raises an error' do
|
|
expect { described_class.for_recipient_email_addresses!(addresses) }.to raise_error(ActiveRecord::RecordNotFound)
|
|
end
|
|
end
|
|
|
|
context 'with keys with multiple UIDs' do
|
|
let!(:multipgp_key) { create(:'pgp_key/multipgp2@example.com') }
|
|
let(:addresses) { %w[pgp1@example.com pgp2@example.com pgp3@example.com multipgp1@example.com multipgp2@example.com] }
|
|
|
|
it 'returns correct keys' do
|
|
expect(described_class.for_recipient_email_addresses!(addresses)).to include(pgp_key1, pgp_key2, pgp_key3, multipgp_key)
|
|
end
|
|
end
|
|
|
|
context 'with active domain alias feature' do
|
|
before do
|
|
Setting.set('pgp_recipient_alias_configuration', true)
|
|
end
|
|
|
|
let!(:pgp_key3) { create(:pgp_key, fixture: 'pgp3@example.com', domain_alias: 'domain3.com') }
|
|
|
|
let(:addresses) { %w[pgp1@example.com pgp2@example.com example@domain3.com] }
|
|
|
|
it 'returns correct keys' do
|
|
expect(described_class.for_recipient_email_addresses!(addresses)).to include(pgp_key1, pgp_key2, pgp_key3)
|
|
end
|
|
end
|
|
end
|
|
|
|
describe '.find_by_uid' do
|
|
let!(:pgp_key1) { create(:'pgp_key/pgp1@example.com') }
|
|
|
|
context 'when an existing uid is used' do
|
|
it 'returns the correct key' do
|
|
expect(described_class.find_by_uid('pgp1@example.com')).to eq(pgp_key1) # rubocop:disable Rails/DynamicFindBy
|
|
end
|
|
end
|
|
|
|
context 'when a non-existing uid is used' do
|
|
it 'raises an error' do
|
|
expect { described_class.find_by_uid('pgp123@example.com') }.to raise_error(ActiveRecord::RecordNotFound) # rubocop:disable Rails/DynamicFindBy
|
|
end
|
|
end
|
|
|
|
context 'when a key with a similar uid is present' do
|
|
before do
|
|
create(:'pgp_key/noexpirepgp1@example.com')
|
|
end
|
|
|
|
it 'returns the correct key' do
|
|
expect(described_class.find_by_uid('pgp1@example.com')).to eq(pgp_key1) # rubocop:disable Rails/DynamicFindBy
|
|
end
|
|
end
|
|
|
|
context 'when recipient alias configuration is active' do
|
|
before do
|
|
Setting.set('pgp_recipient_alias_configuration', true)
|
|
end
|
|
|
|
context 'when there is no match for the domain' do
|
|
it 'raises an error' do
|
|
expect { described_class.find_by_uid('nicole.braun@zammad.org') }.to raise_error(ActiveRecord::RecordNotFound) # rubocop:disable Rails/DynamicFindBy
|
|
end
|
|
end
|
|
|
|
context 'when there is at least one match for the domain' do
|
|
let!(:pgp_key1) { create(:'pgp_key/pgp1@example.com', domain_alias: 'zammad.org') }
|
|
|
|
it 'returns the correct key' do
|
|
expect(described_class.find_by_uid('nicole.braun@zammad.org')).to eq(pgp_key1) # rubocop:disable Rails/DynamicFindBy
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
describe '.find_all_by_uid' do
|
|
let!(:pgp_key1) { create(:'pgp_key/pgp1@example.com', domain_alias: 'zammad.org') }
|
|
let!(:pgp_key2) { create(:'pgp_key/pgp2@example.com', domain_alias: 'zammad.org') }
|
|
let!(:pgp_key3) { create(:'pgp_key/pgp3@example.com', domain_alias: 'zammad.org') }
|
|
|
|
context 'when there is no match for the uid' do
|
|
it 'returns an empty array' do
|
|
expect(described_class.find_all_by_uid('nicole.braun@zammad.org')).to eq([])
|
|
end
|
|
end
|
|
|
|
context 'when recipient alias configuration is active' do
|
|
before do
|
|
Setting.set('pgp_recipient_alias_configuration', true)
|
|
end
|
|
|
|
context 'when there is no match for the uid' do
|
|
it 'returns an empty array' do
|
|
expect(described_class.find_all_by_uid('nicole.braun@zammad.com')).to eq([])
|
|
end
|
|
end
|
|
|
|
context 'when there is at least one match for the uid' do
|
|
it 'returns the correct keys' do
|
|
expect(described_class.find_all_by_uid('pgp1@example.com')).to include(pgp_key1)
|
|
end
|
|
end
|
|
|
|
context 'when there is more than one match for the uid (domain alias)' do
|
|
it 'returns the correct keys' do
|
|
expect(described_class.find_all_by_uid('nicole.braun@zammad.org')).to include(pgp_key1, pgp_key2, pgp_key3)
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'when recipient alias configuration is inactive' do
|
|
before do
|
|
Setting.set('pgp_recipient_alias_configuration', false)
|
|
end
|
|
|
|
context 'when there is no match for the uid' do
|
|
it 'returns an empty array' do
|
|
expect(described_class.find_all_by_uid('nicole.braun@zammad.org')).to eq([])
|
|
end
|
|
end
|
|
|
|
context 'when there is at least one match for the uid' do
|
|
it 'returns the correct keys' do
|
|
expect(described_class.find_all_by_uid('pgp1@example.com')).to include(pgp_key1)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|