diff options
-rw-r--r-- | app/models/incoming_message.rb | 3 | ||||
-rw-r--r-- | app/models/info_request.rb | 62 | ||||
-rw-r--r-- | app/models/request_mailer.rb | 21 | ||||
-rw-r--r-- | app/views/admin_request/show.rhtml | 1 | ||||
-rw-r--r-- | app/views/request/_correspondence.rhtml | 2 | ||||
-rw-r--r-- | config/environment.rb | 4 | ||||
-rw-r--r-- | db/migrate/024_add_is_bounce_to_incoming_messages.rb | 10 | ||||
-rw-r--r-- | db/schema.rb | 3 | ||||
-rw-r--r-- | todo.txt | 20 |
9 files changed, 84 insertions, 42 deletions
diff --git a/app/models/incoming_message.rb b/app/models/incoming_message.rb index 430cb0423..a45062c60 100644 --- a/app/models/incoming_message.rb +++ b/app/models/incoming_message.rb @@ -19,7 +19,7 @@ # Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved. # Email: francis@mysociety.org; WWW: http://www.mysociety.org/ # -# $Id: incoming_message.rb,v 1.22 2008-01-02 16:04:53 francis Exp $ +# $Id: incoming_message.rb,v 1.23 2008-01-03 18:21:30 francis Exp $ class IncomingMessage < ActiveRecord::Base belongs_to :info_request @@ -132,6 +132,7 @@ class IncomingMessage < ActiveRecord::Base text = text.gsub(self.info_request.public_body.complaint_email, "[" + self.info_request.public_body.short_name + " complaint email]") end text = text.gsub(self.info_request.incoming_email, "[FOI #" + self.info_request.id.to_s + " email]") + text = text.gsub(self.info_request.envelope_email, "[FOI #" + self.info_request.id.to_s + " bounce email]") text = text.gsub(MySociety::Config.get("CONTACT_EMAIL", 'contact@localhost'), "[GovernmentSpy contact email]") # Remove all other emails text = IncomingMessage.remove_email_addresses(text) diff --git a/app/models/info_request.rb b/app/models/info_request.rb index 8447dcbc4..242d7d2a8 100644 --- a/app/models/info_request.rb +++ b/app/models/info_request.rb @@ -17,7 +17,7 @@ # Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved. # Email: francis@mysociety.org; WWW: http://www.mysociety.org/ # -# $Id: info_request.rb,v 1.22 2008-01-02 20:13:01 francis Exp $ +# $Id: info_request.rb,v 1.23 2008-01-03 18:21:30 francis Exp $ require 'digest/sha1' @@ -34,16 +34,18 @@ class InfoRequest < ActiveRecord::Base has_many :incoming_messages has_many :info_request_events +public # Email which public body should use to respond to request. This is in # the format PREFIXrequest-ID-HASH@DOMAIN. Here ID is the id of the # FOI request, and HASH is a signature for that id. def incoming_email - raise "id required to make incoming_email" if not self.id - incoming_email = MySociety::Config.get("INCOMING_EMAIL_PREFIX", "") - incoming_email += "request-" + self.id.to_s - incoming_email += "-" + Digest::SHA1.hexdigest(self.id.to_s + MySociety::Config.get("INCOMING_EMAIL_SECRET", 'dummysecret'))[0,8] - incoming_email += "@" + MySociety::Config.get("INCOMING_EMAIL_DOMAIN", "localhost") - return incoming_email + return self.magic_email("request-") + end + + # Modified version of incoming_email to use in the envelope from, for + # bounce messages. + def envelope_email + return self.magic_email("request-bounce-") end # Return info request corresponding to an incoming email address, or nil if @@ -54,21 +56,24 @@ class InfoRequest < ActiveRecord::Base id = $1.to_i hash = $2 - expected_hash = Digest::SHA1.hexdigest(id.to_s + MySociety::Config.get("INCOMING_EMAIL_SECRET", 'dummysecret'))[0,8] - #print "expected: " + expected_hash + "\nhash: " + hash + "\n" - if hash != expected_hash - return nil - else - return self.find(id) - end + return self.find_by_magic_email(id, hash) + end + + def self.find_by_envelope_email(incoming_email) + incoming_email =~ /request-bounce-(\d+)-([a-z0-9]+)/ + id = $1.to_i + hash = $2 + + return self.find_by_magic_email(id, hash) end # A new incoming email to this request - def receive(email, raw_email) + def receive(email, raw_email, is_bounce) incoming_message = IncomingMessage.new incoming_message.raw_data = raw_email + incoming_message.is_bounce = is_bounce incoming_message.info_request = self - incoming_message.save + incoming_message.save! RequestMailer.deliver_new_response(self, incoming_message) end @@ -153,6 +158,31 @@ class InfoRequest < ActiveRecord::Base excerpt.sub!(/Dear .+,/, "") return excerpt end + + protected + + # Called by incoming_email and envelope_email + def magic_email(prefix_part) + raise "id required to make magic" if not self.id + magic_email = MySociety::Config.get("INCOMING_EMAIL_PREFIX", "") + magic_email += prefix_part + self.id.to_s + magic_email += "-" + Digest::SHA1.hexdigest(self.id.to_s + MySociety::Config.get("INCOMING_EMAIL_SECRET", 'dummysecret'))[0,8] + magic_email += "@" + MySociety::Config.get("INCOMING_EMAIL_DOMAIN", "localhost") + return magic_email + end + + # Called by find_by_incoming_email and find_by_envelope_email + def self.find_by_magic_email(id, hash) + expected_hash = Digest::SHA1.hexdigest(id.to_s + MySociety::Config.get("INCOMING_EMAIL_SECRET", 'dummysecret'))[0,8] + #print "expected: " + expected_hash + "\nhash: " + hash + "\n" + if hash != expected_hash + return nil + else + return self.find(id) + end + end + + end diff --git a/app/models/request_mailer.rb b/app/models/request_mailer.rb index 5c5e33065..13bb5fdab 100644 --- a/app/models/request_mailer.rb +++ b/app/models/request_mailer.rb @@ -4,12 +4,13 @@ # Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved. # Email: francis@mysociety.org; WWW: http://www.mysociety.org/ # -# $Id: request_mailer.rb,v 1.13 2008-01-02 15:45:00 francis Exp $ +# $Id: request_mailer.rb,v 1.14 2008-01-03 18:21:30 francis Exp $ class RequestMailer < ActionMailer::Base def initial_request(info_request, outgoing_message) @from = info_request.incoming_email + headers 'Sender' => info_request.envelope_email @recipients = info_request.recipient_email @subject = 'Freedom of Information Request - ' + info_request.title @body = {:info_request => info_request, :outgoing_message => outgoing_message, @@ -48,20 +49,26 @@ class RequestMailer < ActionMailer::Base def receive(email, raw_email) # Find which info requests the email is for - info_requests = [] + reply_info_requests = [] + bounce_info_requests = [] for address in (email.to || []) + (email.cc || []) - info_request = InfoRequest.find_by_incoming_email(address) - info_requests.push(info_request) if info_request + reply_info_request = InfoRequest.find_by_incoming_email(address) + reply_info_requests.push(reply_info_request) if reply_info_request + bounce_info_request = InfoRequest.find_by_envelope_email(address) + bounce_info_requests.push(bounce_info_request) if bounce_info_request end # Nothing found - if info_requests.size == 0 + if reply_info_requests.size == 0 && bounce_info_requests.size == 0 RequestMailer.deliver_bounced_message(email) end # Send the message to each request - for info_request in info_requests - info_request.receive(email, raw_email) + for reply_info_request in reply_info_requests + reply_info_request.receive(email, raw_email, false) + end + for bounce_info_request in bounce_info_requests + bounce_info_request.receive(email, raw_email, true) end end diff --git a/app/views/admin_request/show.rhtml b/app/views/admin_request/show.rhtml index ddf2191b5..b3ad12083 100644 --- a/app/views/admin_request/show.rhtml +++ b/app/views/admin_request/show.rhtml @@ -9,6 +9,7 @@ <% end %> <strong>Public body:</strong> <%=h @info_request.public_body.name %> <br> <strong>Incoming email address:</strong> <%=h @info_request.incoming_email %> <br> +<strong>Envelope email address:</strong> <%=h @info_request.envelope_email %> <br> </p> <%= link_to 'Public page', main_url(request_url(@info_request)) %> diff --git a/app/views/request/_correspondence.rhtml b/app/views/request/_correspondence.rhtml index 50cf39d86..f3f39be7a 100644 --- a/app/views/request/_correspondence.rhtml +++ b/app/views/request/_correspondence.rhtml @@ -13,6 +13,8 @@ <%= public_body_link(@info_request.public_body) %> <% if incoming_message.contains_information %> sent some <strong>useful information</strong> + <% elsif incoming_message.is_bounce %> + replied automatically <% else %> replied <% end %> diff --git a/config/environment.rb b/config/environment.rb index a8f9bba95..8c1d4387b 100644 --- a/config/environment.rb +++ b/config/environment.rb @@ -88,7 +88,9 @@ end ActionController::UrlWriter.default_url_options[:host] = MySociety::Config.get("DOMAIN", 'localhost:3000') # Monkeypatch! Set envelope from in ActionMailer. Code mostly taken from this -# Rails patch, with addition of using mail.from for sendmail if sender not set. +# Rails patch, with addition of using mail.from for sendmail if sender not set +# (the patch does that only for SMTP, when it clearly should consistently do it +# for both) # http://dev.rubyonrails.org/attachment/ticket/7697/action_mailer_base_sender.diff # Which is part of this ticket: # http://dev.rubyonrails.org/ticket/7697 diff --git a/db/migrate/024_add_is_bounce_to_incoming_messages.rb b/db/migrate/024_add_is_bounce_to_incoming_messages.rb new file mode 100644 index 000000000..f81ff4401 --- /dev/null +++ b/db/migrate/024_add_is_bounce_to_incoming_messages.rb @@ -0,0 +1,10 @@ +class AddIsBounceToIncomingMessages < ActiveRecord::Migration + def self.up + add_column :incoming_messages, :is_bounce, :boolean, :default => false + IncomingMessage.update_all "is_bounce = 'f'" + end + + def self.down + remove_column :incoming_messages, :is_bounce + end +end diff --git a/db/schema.rb b/db/schema.rb index 38257f742..30c9570ec 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -2,7 +2,7 @@ # migrations feature of ActiveRecord to incrementally modify your database, and # then regenerate this schema definition. -ActiveRecord::Schema.define(:version => 23) do +ActiveRecord::Schema.define(:version => 24) do create_table "incoming_messages", :force => true do |t| t.column "info_request_id", :integer @@ -11,6 +11,7 @@ ActiveRecord::Schema.define(:version => 23) do t.column "updated_at", :datetime t.column "user_classified", :boolean, :default => false t.column "contains_information", :boolean + t.column "is_bounce", :boolean, :default => false end create_table "info_request_events", :force => true do |t| @@ -19,14 +19,12 @@ BAILII - relationship with law courts, robots.txt ? Next ==== +Remove security warning from admin pages + Make response messages go to a mailbox as backup Make it so if the pipe fails, exim tries again rather than sending an error to the public body. Or so errors go to an admin somehow, at the very least. -Track bounce messages via a separate address - - just record if they are bounce, and any DSN, for now - - and say in display "automatic message" - Either rotate log files, or merge with Apache ones Let requester send follow-ups - but to which email address???!! aargh @@ -43,13 +41,11 @@ Remove "Outgoing messages is invalid" error Make it so "mysociety test" can be done on the servers, so it checks any packages are installed Add fixtures for info_request_event +Test sending a message to bounce/envelope-from address Tidying ======= -Do we need to say to the public body "all responses will be published" from a -privacy point of view? - accept-charset="utf-8" on all forms - does it matter if Content-Type of whole page is already UTF-8? @@ -62,9 +58,6 @@ Add SQL database indexes to token / email_token in post_redirects Prevent double posting of same request -If summary is blank, says "title must be filled in" grrrr -Tidy up error message text (like "body must be filled in") on info request form - Set "null" and "default" options more in schema Add SQL foreign keys to database schema execute 'ALTER TABLE researchers ADD CONSTRAINT fk_researchers_departments FOREIGN KEY ( department_id ) REFERENCES departments( id ) ' @@ -87,10 +80,6 @@ Check act to see if can use pseudonym for FOI request? (e.g. somebody messaging creator of a request and it bouncing) where we may reasonably do this, and should say it may happen? -Maybe we SHOULD reveal their email to the public body, why not? - -Say that we would like response by email (not postal address) in footer - Later ===== @@ -107,9 +96,8 @@ Remember me box http://onrails.org/articles/2006/02/18/auto-login Forgotten password link -Check these out for ids +Screen scrape this and add link to it on the public body page http://www.ico.gov.uk/Home/tools_and_resources/decision_notices.aspx -Screen scrape it and add it to the public body page (10:32:14) richard: you just need to count the number of rows of text and compare it to the number of rows in the textbox (10:32:29) richard: then increase the height of the textbox by 1em-ish |