Commit f2f86d42 authored by Nina's avatar Nina

Merge branch 'extend_headers_to_meta' into 'master'

Extend headers to meta

This MR includes the Enc and Sig pseudoheaders in the list of configurable headers. This makes it possible to rearrange or disable them.
Fixes #297

See merge request !147
parents 36b1c331 d0bfe2b6
Pipeline #18091 passed with stages
in 46 minutes and 49 seconds
......@@ -25,6 +25,8 @@ This project adheres to [Semantic Versioning](http://semver.org/).
* In the response to 'X-ADD-KEY', differentiate between 'newly imported' and 'updated' keys.
* Parse keywords up to the first line detected as mail content, this addresses a first part of #249.
### Added
* Extend the pseudoheaders configuration option to support 'sig' and 'enc' as configurable and sortable fields.
## [3.2.3] / 2018-05-14
......
class AddSigEncToHeadersToMetaDefaults < ActiveRecord::Migration
def up
change_column_default :lists, :headers_to_meta, '["from", "to", "cc", "date", "sig", "enc"]'
list_klass = create_list_klass
list_klass.reset_column_information
list_klass.find_each do |list|
if (list.headers_to_meta & ['sig', 'enc']).empty?
list.update(headers_to_meta: list.headers_to_meta + ['sig', 'enc'])
end
end
end
def down
change_column_default :lists, :headers_to_meta, '["from", "to", "cc", "date"]'
list_klass = create_list_klass
list_klass.reset_column_information
list_klass.find_each do |list|
list.update(headers_to_meta: list.headers_to_meta - ['enc','sig'])
end
end
def create_list_klass
# Use a temporary class-definition to be independent of the
# complexities of the actual class.
Class.new(ActiveRecord::Base) do
self.table_name = 'lists'
self.serialize :headers_to_meta, JSON
end
end
end
......@@ -43,6 +43,8 @@ headers_to_meta:
- to
- cc
- date
- sig
- enc
# Preserve the Message-IDs (In-Reply-To, References) from the incoming email.
# This setting can lead to information leakage, as replies are connectable
......
......@@ -283,17 +283,7 @@ module Mail
@dynamic_pseudoheaders || []
end
def standard_pseudoheaders(list)
if @standard_pseudoheaders.present?
return @standard_pseudoheaders
else
@standard_pseudoheaders = []
end
Array(list.headers_to_meta).each do |field|
@standard_pseudoheaders << make_pseudoheader(field.to_s, self.header[field.to_s])
end
def signature_state
# Careful to add information about the incoming signature. GPGME
# throws exceptions if it doesn't know the key.
if self.signature.present?
......@@ -301,22 +291,41 @@ module Mail
# for that manually and provide our own fallback. (Calling
# `signature.key` results in an EOFError in that case.)
if signing_key.present?
msg = signature.to_s
signature_state = signature.to_s
else
# TODO: I18n
msg = "Unknown signature by unknown key 0x#{self.signature.fingerprint}"
signature_state = I18n.t("signature_states.unknown", fingerprint: self.signature.fingerprint)
end
else
# TODO: I18n
msg = "Unsigned"
signature_state = I18n.t("signature_states.unsigned")
end
signature_state
end
def encryption_state
if was_encrypted?
encryption_state = I18n.t("encryption_states.encrypted")
else
encryption_state = I18n.t("encryption_states.unencrypted")
end
encryption_state
end
def standard_pseudoheaders(list)
if @standard_pseudoheaders.present?
return @standard_pseudoheaders
else
@standard_pseudoheaders = []
end
Array(list.headers_to_meta).each do |field|
value = case field.to_s
when 'sig' then signature_state
when 'enc' then encryption_state
else self.header[field.to_s]
end
@standard_pseudoheaders << make_pseudoheader(field.to_s, value)
end
@standard_pseudoheaders << make_pseudoheader(:sig, msg)
# TODO: I18n
@standard_pseudoheaders << make_pseudoheader(
:enc,
was_encrypted? ? 'Encrypted' : 'Unencrypted'
)
@standard_pseudoheaders
end
......
......@@ -45,7 +45,7 @@ module Schleuder
# Subscriptions
logger.debug "Creating clean copy of message"
copy = @mail.clean_copy(true)
copy = @mail.clean_copy(list.headers_to_meta.any?)
list.send_to_subscriptions(copy)
nil
end
......
......@@ -251,6 +251,12 @@ de:
invalid_input: "Ungültige Angabe. Gültig sind: URLs, OpenPGP-Fingerabdrücke, oder Emailadressen."
pseudoheaders:
stripped_html_from_multialt: Diese Email enthielt einen alternativen HTML-Teil, der PGP-Daten beinhaltete. Der HTML-Teil wurde entfernt, um die Email sauberer analysieren zu können.
signature_states:
unknown: "Unbekannte Signatur von unbekanntem Schlüssel 0x%{fingerprint}"
unsigned: "Unsigniert"
encryption_states:
encrypted: "Verschlüsselt"
unencrypted: "Unverschlüsselt"
activerecord:
errors:
......
......@@ -255,6 +255,12 @@ en:
invalid_input: "Invalid input. Allowed are: URLs, OpenPGP-fingerprints, or email-addresses."
pseudoheaders:
stripped_html_from_multialt: This message included an alternating HTML-part that contained PGP-data. The HTML-part was removed to enable parsing the message more properly.
signature_states:
unknown: "Unknown signature by unknown key 0x%{fingerprint}"
unsigned: "Unsigned"
encryption_states:
encrypted: "Encrypted"
unencrypted: "Unencrypted"
activerecord:
errors:
......
require 'spec_helper'
require './db/migrate/20180110203100_add_sig_enc_to_headers_to_meta_defaults.rb'
describe 'AddSigEncToHeadersToMetaDefaults' do
let(:migrations_paths) { ENV['SCHLEUDER_ROOT'] + '/db/migrate' }
let(:migration_under_test) { 20180110203100 }
let(:previous_migration) { 20170713215059 }
describe 'up' do
it 'sets the column defaults' do
ActiveRecord::Migrator.migrate(migrations_paths, previous_migration)
list_klass = create_list_klass
list_klass.reset_column_information
ActiveRecord::Migrator.migrate(migrations_paths, migration_under_test)
list_klass.reset_column_information
expect(list_klass.column_defaults['headers_to_meta']).to eql(["from", "to", "cc", "date", "sig", "enc"])
end
it 'adds sig and enc to headers_to_meta for lists wihtout the attributes' do
ActiveRecord::Migrator.migrate(migrations_paths, previous_migration)
list_klass = create_list_klass
list = create(:list, headers_to_meta: list_klass.column_defaults['headers_to_meta'])
expect(list.headers_to_meta).not_to include('enc', 'sig')
ActiveRecord::Migrator.migrate(migrations_paths, migration_under_test)
list_klass.reset_column_information
list.reload
expect(list.headers_to_meta).to include('enc', 'sig')
end
it 'does not add sig and enc to headers to meta if the attributes already exist' do
headers_to_meta_including_sig_and_enc = ["from", "to", "cc", "date", "sig", "enc"]
ActiveRecord::Migrator.migrate(migrations_paths, previous_migration)
list_klass = create_list_klass
list = create(:list, headers_to_meta: headers_to_meta_including_sig_and_enc)
expect(list.headers_to_meta).to eql headers_to_meta_including_sig_and_enc
ActiveRecord::Migrator.migrate(migrations_paths, migration_under_test)
list_klass.reset_column_information
list.reload
expect(list.headers_to_meta).to eql headers_to_meta_including_sig_and_enc
end
end
describe 'down' do
it 'sets the column defaults' do
ActiveRecord::Migrator.migrate(migrations_paths, migration_under_test)
list_klass = create_list_klass
list_klass.reset_column_information
ActiveRecord::Migrator.migrate(migrations_paths, previous_migration)
list_klass.reset_column_information
expect(list_klass.column_defaults['headers_to_meta']).to eql(["from", "to", "cc", "date"])
end
it 'removes sig and enc from headers_to_meta from existing lists' do
ActiveRecord::Migrator.migrate(migrations_paths, migration_under_test)
list_klass = create_list_klass
list_klass.reset_column_information
list = create(:list, headers_to_meta: list_klass.column_defaults['headers_to_meta'])
expect(list.headers_to_meta).to include('enc', 'sig')
ActiveRecord::Migrator.migrate(migrations_paths, previous_migration)
list_klass.reset_column_information
list.reload
expect(list.headers_to_meta).not_to include('enc', 'sig')
end
end
def create_list_klass
Class.new(ActiveRecord::Base) do
self.table_name = 'lists'
self.serialize :headers_to_meta, JSON
end
end
end
......@@ -31,6 +31,24 @@ describe Schleuder::Runner do
teardown_list_and_mailer(list)
end
it "contains the specified pseudoheaders in the correct order" do
list = create(:list, send_encrypted_only: false, headers_to_meta: ["from", "sig"])
list.subscribe("admin@example.org", nil, true)
mail = File.read("spec/fixtures/mails/plain/thunderbird.eml")
Schleuder::Runner.new().run(mail, list.email)
message = Mail::TestMailer.deliveries.first
content_part = message.parts.first
pseudoheaders = "From: Nina Siessegger <schleuder@example.org>\nSig: Unsigned"
expect(content_part.parts.first.body).to include(pseudoheaders)
expect(content_part.parts.first.body).not_to include('To:')
expect(content_part.parts.first.body).not_to include('Enc:')
expect(content_part.parts.first.body).not_to include('Date:')
teardown_list_and_mailer(list)
end
it "doesn't have unwanted headerlines from the original message" do
list = create(:list, send_encrypted_only: false)
list.subscribe("admin@example.org", nil, true)
......
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