Commit f177259d authored by ng's avatar ng

implement method to pin keys

Similar to the administrative command refresh_keys we now offer a
command pin_keys, which will pin subscriptions without a fingerprint
to a distinct key, if one can be found.

Closes #225
parent ea38d2db
......@@ -5,6 +5,10 @@ This project adheres to [Semantic Versioning](http://semver.org/).
## [3.1.x] / 2017-06-xx (unreleased)
### Added
* Provide an administrative command `pin_keys`, to pin subscriptions to a distinct key (#225)
### Fixed
* Do not detect Cron-Emails as bounce (#205)
......
......@@ -65,14 +65,12 @@ module Schleuder
desc 'refresh_keys', "Refresh all keys of all list from the keyservers sequentially (one by one). (This is supposed to be run from cron weekly.)"
def refresh_keys
List.all.each do |list|
I18n.locale = list.language
output = list.refresh_keys
if output.present?
msg = "#{I18n.t('refresh_keys_intro', email: list.email)}\n\n#{output}"
list.logger.notify_admin(msg, nil, I18n.t('refresh_keys'))
end
end
work_on_lists(:refresh_keys)
end
desc 'pin_keys', "Find keys for subscriptions without a pinned key and try to pin a certain key"
def pin_keys
work_on_lists(:pin_keys)
end
desc 'install', "Set-up or update Schleuder environment (create folders, copy files, fill the database)."
......@@ -304,5 +302,17 @@ Please notify the users and admins of this list of these changes.
end
end
end
private
def work_on_lists(subj)
List.all.each do |list|
I18n.locale = list.language
output = list.send(subj)
if output.present?
msg = "#{I18n.t("#{subj}_intro", email: list.email)}\n\n#{output}"
list.logger.notify_admin(msg, nil, I18n.t(subj))
end
end
end
end
end
......@@ -89,6 +89,10 @@ module Schleuder
subscriptions.where(admin: true)
end
def subscriptions_without_fingerprint
subscriptions.without_fingerprint
end
def key(fingerprint=self.fingerprint)
keys(fingerprint).first
end
......@@ -179,6 +183,19 @@ module Schleuder
gpg.fetch_key(input)
end
def pin_keys
updated_emails = subscriptions_without_fingerprint.collect do |subscription|
key = distinct_key(subscription.email)
if key
subscription.update(fingerprint: key.fingerprint)
"#{subscription.email}: #{key.fingerprint}"
else
nil
end
end
updated_emails.compact.join("\n")
end
def self.by_recipient(recipient)
listname = recipient.gsub(/-(sendkey|request|owner|bounce)@/, '@')
where(email: listname).first
......
......@@ -12,6 +12,8 @@ module Schleuder
default_scope { order(:email) }
scope :without_fingerprint, -> { where(fingerprint: [nil,'']) }
def to_s
email
end
......
......@@ -144,6 +144,8 @@ de:
missed_message_due_to_unusable_key: "Du hast eine Email von %{list_email} verpasst weil mit deinem Abo kein (benutzbarer) OpenPGP-Schlüssel verknüpft ist. Bitte kümmere dich darum."
refresh_keys: Schlüsselaktualisierung
refresh_keys_intro: "Die Aktualisierung aller Schlüssel des Schlüsselrings für Liste %{email} ergab dies:"
pin_keys: Schlüsselpinning
pin_keys_intro: "Die Überprüfung aller Abos der Liste %{email} ergab, dass wir für folgende Abos einen Schlüssel zur Verwendung festgelegt haben:"
key_updated: Schlüssel %{fingerprint} wurde aktualisiert (%{states}).
key_fetched: Schlüssel %{fingerprint} wurde geholt (%{states}).
import_states:
......
......@@ -144,6 +144,8 @@ en:
missed_message_due_to_unusable_key: "You missed an email from %{list_email} because your subscription isn't associated with a (usable) OpenPGP key. Please fix this."
refresh_keys: Keys update
refresh_keys_intro: "Refreshing all keys from the keyring of list %{email} resulted in this:"
pin_keys: Keys pinning
pin_keys_intro: "While checking all subscriptions of list %{email} we were pinning a matching key for the following subscriptions:"
key_updated: Key %{fingerprint} was updated (%{states}).
key_fetched: Key %{fingerprint} was fetched (%{states}).
import_states:
......
......@@ -94,7 +94,6 @@ describe 'cli' do
expect(list.subscriptions.where(email: "old@example.org").first.fingerprint).to eql("6EE51D78FD0B33DE65CCF69D2104E20E20889F66")
expect(list.subscriptions.where(email: "schleuder2@example.org").first.fingerprint).to eql("C4D60F8833789C7CAA44496FD3FFA6613AB10ECE")
expect(list.subscriptions.where(email: "someone@example.org").first.fingerprint).to eql('')
end
it "does not fail on duplicated v2 subscriptions" do
......@@ -169,6 +168,41 @@ describe 'cli' do
expect(mail.to_s).to match(/gpgkeys: .* error .* connect/)
end
teardown_list_and_mailer(list)
end
end
context '#pin_keys' do
it 'pins fingerprints on not yet set keys' do
list = create(:list)
list.subscribe("admin@example.org", nil, true)
list.subscribe("schleuder2@example.org", nil, false)
list.import_key(File.read('spec/fixtures/example_key.txt'))
expect(list.subscriptions_without_fingerprint.size).to eq 2
Cli.new.pin_keys
expect(list.subscriptions_without_fingerprint.size).to eq 1
expect(list.subscriptions_without_fingerprint.collect(&:email)).to eq ['admin@example.org']
mail = Mail::TestMailer.deliveries.first
expect(Mail::TestMailer.deliveries.length).to eq 1
expect(mail.first_plaintext_part.body.to_s).to eql("While checking all subscriptions of list #{list.email} we were pinning a matching key for the following subscriptions:\n\nschleuder2@example.org: C4D60F8833789C7CAA44496FD3FFA6613AB10ECE")
teardown_list_and_mailer(list)
end
it 'does not report anything if nothing was done' do
list = create(:list)
list.subscribe("admin@example.org", nil, true)
list.subscribe("schleuder2@example.org", nil, false)
expect(list.subscriptions_without_fingerprint.size).to eq 2
Cli.new.pin_keys
expect(list.subscriptions_without_fingerprint.size).to eq 2
expect(Mail::TestMailer.deliveries.empty?).to eq true
teardown_list_and_mailer(list)
end
end
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment