Fixes #4029 - Cannot encrypt if multiple S/MIME certificates exist and one is expired.
This commit is contained in:
parent
b85bd1fe79
commit
92d19a6221
2 changed files with 27 additions and 4 deletions
|
@ -1,6 +1,8 @@
|
||||||
# Copyright (C) 2012-2022 Zammad Foundation, https://zammad-foundation.org/
|
# Copyright (C) 2012-2022 Zammad Foundation, https://zammad-foundation.org/
|
||||||
|
|
||||||
class SMIMECertificate < ApplicationModel
|
class SMIMECertificate < ApplicationModel
|
||||||
|
default_scope { order('not_after_at DESC, not_before_at DESC, id DESC') }
|
||||||
|
|
||||||
validates :fingerprint, uniqueness: { case_sensitive: true }
|
validates :fingerprint, uniqueness: { case_sensitive: true }
|
||||||
|
|
||||||
def self.parts(raw)
|
def self.parts(raw)
|
||||||
|
@ -38,8 +40,8 @@ class SMIMECertificate < ApplicationModel
|
||||||
# @return [SMIMECertificate, nil] The found certificate record or nil
|
# @return [SMIMECertificate, nil] The found certificate record or nil
|
||||||
def self.for_sender_email_address(address)
|
def self.for_sender_email_address(address)
|
||||||
downcased_address = address.downcase
|
downcased_address = address.downcase
|
||||||
where.not(private_key: nil).find_each.detect do |certificate|
|
where.not(private_key: nil).all.as_batches do |certificate|
|
||||||
certificate.email_addresses.include?(downcased_address)
|
return certificate if certificate.email_addresses.include?(downcased_address)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -55,7 +57,7 @@ class SMIMECertificate < ApplicationModel
|
||||||
def self.for_recipipent_email_addresses!(addresses)
|
def self.for_recipipent_email_addresses!(addresses)
|
||||||
certificates = []
|
certificates = []
|
||||||
remaining_addresses = addresses.map(&:downcase)
|
remaining_addresses = addresses.map(&:downcase)
|
||||||
find_each do |certificate|
|
all.as_batches do |certificate|
|
||||||
|
|
||||||
# intersection of both lists
|
# intersection of both lists
|
||||||
cerfiticate_for = certificate.email_addresses & remaining_addresses
|
cerfiticate_for = certificate.email_addresses & remaining_addresses
|
||||||
|
|
|
@ -107,7 +107,7 @@ RSpec.describe SMIMECertificate, type: :model do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns certificates' do
|
it 'returns certificates' do
|
||||||
expect(described_class.for_recipipent_email_addresses!(lookup_addresses)).to eq(certificates)
|
expect(described_class.for_recipipent_email_addresses!(lookup_addresses)).to include(*certificates)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -196,4 +196,25 @@ RSpec.describe SMIMECertificate, type: :model do
|
||||||
it 'ensures uniqueness of records' do
|
it 'ensures uniqueness of records' do
|
||||||
expect { create_list(:smime_certificate, 2, fixture: 'smime1@example.com') }.to raise_error(ActiveRecord::RecordInvalid, %r{Validation failed})
|
expect { create_list(:smime_certificate, 2, fixture: 'smime1@example.com') }.to raise_error(ActiveRecord::RecordInvalid, %r{Validation failed})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe 'Cannot encrypt if multiple S/MIME certificates exist and one is expired #4029' do
|
||||||
|
let(:lookup_address) { 'smime1@example.com' }
|
||||||
|
|
||||||
|
before do
|
||||||
|
create(:smime_certificate, :with_private, fixture: lookup_address, not_before_at: '2021-04-07', not_after_at: '2021-04-07', fingerprint: 'A')
|
||||||
|
create(:smime_certificate, :with_private, fixture: lookup_address, not_before_at: '2022-04-07', not_after_at: '2042-04-07', fingerprint: 'B')
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '.for_sender_email_address' do
|
||||||
|
it 'does return the latest certificate when there is also an old expired certificate' do
|
||||||
|
expect(described_class.for_sender_email_address('smime1@example.com').fingerprint).to eq('B')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '.for_recipipent_email_addresses!' do
|
||||||
|
it 'does return the latest certificate when there is also an old expired certificate' do
|
||||||
|
expect(described_class.for_recipipent_email_addresses!(['smime1@example.com']).first.fingerprint).to eq('B')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue