aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--app/models/incoming_message.rb3
-rw-r--r--app/models/info_request.rb62
-rw-r--r--app/models/request_mailer.rb21
-rw-r--r--app/views/admin_request/show.rhtml1
-rw-r--r--app/views/request/_correspondence.rhtml2
-rw-r--r--config/environment.rb4
-rw-r--r--db/migrate/024_add_is_bounce_to_incoming_messages.rb10
-rw-r--r--db/schema.rb3
-rw-r--r--todo.txt20
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|
diff --git a/todo.txt b/todo.txt
index 247a17bc9..18d6fa23a 100644
--- a/todo.txt
+++ b/todo.txt
@@ -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