Commit bc7f412a authored by ng's avatar ng
Browse files

Improve parsing of keywords - first part of #249

This changes the way how we parse for keywords to the following
approach:

  1. Ignore any empty/pure-whitespace lines at the beginning of
     the first plain_text_part message.
  2. If you match something /^X\-.*/ start matching for plugins,
     else abort.
  3. Once you matched a plugin, but you have a new
     non-empty/pure-whitespace line starting with something
     different than /^X\-.*/ abort looking for plugin names.

This fixes the most common problems with lines starting with `X-`
further down in the body of an email, while keeping all of the
existing behavior and functionality.

Any further improvements to the code base and the parsing of
mails as discussed in #249 is postponed to future work. Tis work
should go together with work in #359 which will allow to change
the structure of plugins.
parent 89d60b0b
......@@ -15,6 +15,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
* The output of the keywords 'X-ADD-KEY' and 'X-DELETE-KEY' now also show the "oneline"-format to represent keys (which includes fingerprint, primary email-address, date of generation and possible expiry). (#295)
* 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.
## [3.2.3] / 2018-05-14
......
......@@ -222,15 +222,19 @@ module Mail
end
@keywords = []
look_for_keywords = true
lines = part.decoded.lines.map do |line|
# TODO: Find multiline arguments (add-key). Currently add-key has to
# read the whole body and hope for the best.
if line.match(/^x-([^:\s]*)[:\s]*(.*)/i)
command = $1.strip.downcase
arguments = $2.to_s.strip.downcase.split(/[,; ]{1,}/)
if look_for_keywords && (m = line.match(/^x-([^:\s]*)[:\s]*(.*)/i))
command = m[1].strip.downcase
arguments = m[2].to_s.strip.downcase.split(/[,; ]{1,}/)
@keywords << [command, arguments]
nil
else
if look_for_keywords && line.match(/\S+/i)
look_for_keywords = false
end
line
end
end
......
......@@ -1390,6 +1390,61 @@ describe "user sends keyword" do
teardown_list_and_mailer(list)
end
it "does not parse keywords once the mail body started" do
list = create(:list, public_footer: "-- \nblablabla")
list.subscribe("schleuder@example.org", '59C71FB38AEE22E091C78259D06350440F759BD3', true)
ENV['GNUPGHOME'] = list.listdir
mail = Mail.new
mail.to = list.email
mail.from = list.admins.first.email
gpg_opts = {
encrypt: true,
keys: {list.email => list.fingerprint},
sign: true,
sign_as: list.admins.first.fingerprint
}
mail.gpg(gpg_opts)
content_body = <<EOS
Hello again!
Did you know that you can resend emails using the following keyword:
x-resend: foo@example.com
Don't forget to prefix it with
x-list-name: yourlist@example.com
Otherwise it won't be sent out. What a nice trick!
Best
EOS
mail.body = "x-list-name: #{list.email}\nX-resend: someone@example.org\n#{content_body}"
mail.deliver
encrypted_mail = Mail::TestMailer.deliveries.first
Mail::TestMailer.deliveries.clear
begin
Schleuder::Runner.new().run(encrypted_mail.to_s, list.email)
rescue SystemExit
end
expect(Mail::TestMailer.deliveries.length).to eql(2)
raw = Mail::TestMailer.deliveries.first
resent_message = raw.verify
resent_message_body = resent_message.parts.map { |p| p.body.to_s }.join
raw = Mail::TestMailer.deliveries.last
message = Mail.create_message_to_list(raw.to_s, list.email, list).setup
expect(message.to).to eql(['schleuder@example.org'])
expect(message.to_s).to include("Resent: Unencrypted to someone@example.org")
expect(resent_message.to).to include("someone@example.org")
expect(resent_message.to_s).not_to include("Resent: Unencrypted to someone@example.org")
expect(resent_message_body).to eql(content_body + list.public_footer.to_s)
teardown_list_and_mailer(list)
end
it "x-resend does not include internal_footer" do
list = create(
:list,
......
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