aboutsummaryrefslogtreecommitdiffstats
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/controllers/admin_user_controller.rb1
-rw-r--r--app/controllers/application_controller.rb11
-rw-r--r--app/controllers/general_controller.rb11
-rw-r--r--app/controllers/request_controller.rb8
-rw-r--r--app/models/foi_attachment.rb6
-rw-r--r--app/models/incoming_message.rb3
-rw-r--r--app/models/user.rb22
-rw-r--r--app/views/admin_user/_form.rhtml8
-rw-r--r--app/views/user/rate_limited.rhtml5
-rw-r--r--app/views/user/show.rhtml35
10 files changed, 71 insertions, 39 deletions
diff --git a/app/controllers/admin_user_controller.rb b/app/controllers/admin_user_controller.rb
index 5d90e74fe..12b4e553f 100644
--- a/app/controllers/admin_user_controller.rb
+++ b/app/controllers/admin_user_controller.rb
@@ -45,6 +45,7 @@ class AdminUserController < AdminController
@admin_user.admin_level = params[:admin_user][:admin_level]
@admin_user.ban_text = params[:admin_user][:ban_text]
@admin_user.about_me = params[:admin_user][:about_me]
+ @admin_user.no_limit = params[:admin_user][:no_limit]
if @admin_user.valid?
@admin_user.save!
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 8fc6c3792..1849f23f3 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -178,14 +178,13 @@ class ApplicationController < ActionController::Base
end
def foi_fragment_cache_path(param)
- path = foi_fragment_cache_part_path(param)
- path = "/views" + path
- foi_cache_path = File.join(File.dirname(__FILE__), '../../cache')
+ path = File.join(RAILS_ROOT, 'cache', 'views', foi_fragment_cache_part_path(param))
max_file_length = 255 - 35 # we subtract 35 because tempfile
# adds on a variable number of
# characters
- return File.join(foi_cache_path, path)[0...max_file_length]
+ return File.join(File.split(path).map{|x| x[0...max_file_length]})
end
+
def foi_fragment_cache_all_for_request(info_request)
# return stub path so admin can expire it
first_three_digits = info_request.id.to_s()[0..2]
@@ -355,9 +354,7 @@ class ApplicationController < ActionController::Base
@sortby = sortby
# Work out sorting method
- order_pair = order_to_sort_by(@sortby)
- order = order_pair[0]
- ascending = order_pair[1]
+ order, ascending = order_to_sort_by(@sortby)
# Peform the search
@per_page = per_page
diff --git a/app/controllers/general_controller.rb b/app/controllers/general_controller.rb
index 8ac41b05a..82b1b8629 100644
--- a/app/controllers/general_controller.rb
+++ b/app/controllers/general_controller.rb
@@ -45,20 +45,21 @@ class GeneralController < ApplicationController
:joins => :translations)
end
end
- # Get some successful requests #
+ # Get some successful requests
begin
query = 'variety:response (status:successful OR status:partially_successful)'
- # query = 'variety:response' # XXX debug
- sortby = "described"
+ sortby = "newest"
max_count = 5
xapian_object = perform_search([InfoRequestEvent], query, sortby, 'request_title_collapse', max_count)
@request_events = xapian_object.results.map { |r| r[:model] }
- @request_events = @request_events.sort_by { |e| e.described_at }.reverse
+
+ # If there are not yet enough successful requests, fill out the list with
+ # other requests
if @request_events.count < max_count
query = 'variety:sent'
xapian_object = perform_search([InfoRequestEvent], query, sortby, 'request_title_collapse', max_count-@request_events.count)
more_events = xapian_object.results.map { |r| r[:model] }
- @request_events += more_events.sort_by { |e| e.described_at }.reverse
+ @request_events += more_events
end
rescue
@request_events = []
diff --git a/app/controllers/request_controller.rb b/app/controllers/request_controller.rb
index a70e8d16c..fc1ffdd75 100644
--- a/app/controllers/request_controller.rb
+++ b/app/controllers/request_controller.rb
@@ -208,8 +208,12 @@ class RequestController < ApplicationController
# Banned from making new requests?
if !authenticated_user.nil? && !authenticated_user.can_file_requests?
- @details = authenticated_user.can_fail_html
- render :template => 'user/banned'
+ if authenticated_user.exceeded_limit?
+ render :template => 'user/rate_limited'
+ else
+ @details = authenticated_user.can_fail_html
+ render :template => 'user/banned'
+ end
return
end
diff --git a/app/models/foi_attachment.rb b/app/models/foi_attachment.rb
index 74346227b..da92d1c2d 100644
--- a/app/models/foi_attachment.rb
+++ b/app/models/foi_attachment.rb
@@ -38,7 +38,11 @@ class FoiAttachment < ActiveRecord::Base
BODY_MAX_DELAY = 5
def directory
- base_dir = File.join(File.dirname(__FILE__), "../../cache", "attachments_#{ENV['RAILS_ENV']}")
+ rails_env = ENV['RAILS_ENV']
+ if rails_env.nil? || rails_env.empty?
+ raise "$RAILS_ENV is not set"
+ end
+ base_dir = File.join(File.dirname(__FILE__), "../../cache", "attachments_#{rails_env}")
return File.join(base_dir, self.hexdigest[0..2])
end
diff --git a/app/models/incoming_message.rb b/app/models/incoming_message.rb
index 91f1cf7c0..131970ba6 100644
--- a/app/models/incoming_message.rb
+++ b/app/models/incoming_message.rb
@@ -127,6 +127,9 @@ class IncomingMessage < ActiveRecord::Base
# The following fields may be absent; we treat them as cached
# values in case we want to regenerate them (due to mail
# parsing bugs, etc).
+ if self.raw_email.nil?
+ raise "Incoming message id=#{id} has no raw_email"
+ end
if (!force.nil? || self.last_parsed.nil?)
ActiveRecord::Base.transaction do
self.extract_attachments!
diff --git a/app/models/user.rb b/app/models/user.rb
index b6839aa31..2193805ea 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -19,6 +19,7 @@
# locale :string(255)
# email_bounced_at :datetime
# email_bounce_message :text default(""), not null
+# no_limit :boolean default(FALSE), not null
#
# models/user.rb:
@@ -256,7 +257,7 @@ class User < ActiveRecord::Base
end
def User.owns_every_request?(user)
- !user.nil? && user.owns_every_request?
+ !user.nil? && user.owns_every_request?
end
# Can the user see every request, even hidden ones?
@@ -274,7 +275,18 @@ class User < ActiveRecord::Base
end
# Various ways the user can be banned, and text to describe it if failed
def can_file_requests?
- self.ban_text.empty?
+ self.ban_text.empty? && !self.exceeded_limit?
+ end
+ def exceeded_limit?
+ # Some users have no limit
+ return false if self.no_limit
+
+ # Has the user issued as many as MAX_REQUESTS_PER_USER_PER_DAY requests in the past 24 hours?
+ daily_limit = MySociety::Config.get("MAX_REQUESTS_PER_USER_PER_DAY")
+ return false if daily_limit.nil?
+ recent_requests = InfoRequest.count(:conditions => ["user_id = ? and created_at > now() - '1 day'::interval", self.id])
+
+ return (recent_requests >= daily_limit)
end
def can_make_followup?
self.ban_text.empty?
@@ -286,7 +298,11 @@ class User < ActiveRecord::Base
self.ban_text.empty?
end
def can_fail_html
- text = self.ban_text.strip
+ if ban_text
+ text = self.ban_text.strip
+ else
+ raise "Unknown reason for ban"
+ end
text = CGI.escapeHTML(text)
text = MySociety::Format.make_clickable(text, :contract => 1)
text = text.gsub(/\n/, '<br>')
diff --git a/app/views/admin_user/_form.rhtml b/app/views/admin_user/_form.rhtml
index ba2bd8f8b..be69d9a80 100644
--- a/app/views/admin_user/_form.rhtml
+++ b/app/views/admin_user/_form.rhtml
@@ -8,10 +8,10 @@
<p><label for="admin_user_email">Email</label> (<strong>you must</strong> first validate this)<br/>
<%= text_field 'admin_user', 'email', :size => 60 %></p>
-<p><label for="admin_level">Admin level</label> (<strong>none</strong> or <strong>super</strong>; this is for admin features and links which are in the site proper)<br/>
+<p><label for="admin_user_admin_level">Admin level</label> (<strong>none</strong> or <strong>super</strong>; this is for admin features and links which are in the site proper)<br/>
<%= text_field 'admin_user', 'admin_level', :size => 60 %></p>
-<p><label for="ban_text">Ban text</label> <small>(if not blank will stop the
+<p><label for="admin_user_ban_text">Ban text</label> <small>(if not blank will stop the
user from filing new requests, making annotations or messaging other users;
the text is shown in public on the user's page and when they try to do a
forbidden action; write in the second person (you); see
@@ -19,7 +19,9 @@
<%= text_area 'admin_user', 'ban_text', :cols => 60, :rows => 3 %></p>
-<p><label for="about_me">About me</label> (user's own text on their profile, format like comments):<br/>
+<p><label for="admin_user_about_me">About me</label> (user's own text on their profile, format like comments):<br/>
<%= text_area 'admin_user', 'about_me', :cols => 60, :rows => 3 %></p>
+<p><%= check_box 'admin_user', 'no_limit' %>
+<label for="admin_user_no_limit">No rate limit</label> (disable the limit on daily requests)</p>
diff --git a/app/views/user/rate_limited.rhtml b/app/views/user/rate_limited.rhtml
new file mode 100644
index 000000000..d513cec9e
--- /dev/null
+++ b/app/views/user/rate_limited.rhtml
@@ -0,0 +1,5 @@
+<% @title = "Too many requests" %>
+
+<h1><%=@title%></h1>
+
+<p><%= _('You have made too many requests today. Please try again tomorrow.')%></p>
diff --git a/app/views/user/show.rhtml b/app/views/user/show.rhtml
index a4466f5f4..8f1803442 100644
--- a/app/views/user/show.rhtml
+++ b/app/views/user/show.rhtml
@@ -81,7 +81,7 @@
<div id="user_public_banned">
<p>
<strong>
- <%= _('This user has been banned from {{site_name}} ', :site_name=>site_name)%>
+ <%= _('This user has been banned from {{site_name}} ', :site_name=>site_name)%>
</strong>
</p>
<p>
@@ -125,17 +125,16 @@
<% if @show_requests %>
<div id="user_profile_search">
- <% form_tag(show_user_url, :method => "get", :id=>"search_form") do %>
- <div>
- <%= text_field_tag(:user_query, params[:user_query]) %>
- <% if @is_you %>
- <%= submit_tag(_("Search your contributions")) %>
- <% else %>
- <%= submit_tag(_("Search contributions by this person")) %>
- <% end %>
- </div>
- <% end %>
-
+ <% form_tag(show_user_url, :method => "get", :id=>"search_form") do %>
+ <div>
+ <%= text_field_tag(:user_query, params[:user_query]) %>
+ <% if @is_you %>
+ <%= submit_tag(_("Search your contributions")) %>
+ <% else %>
+ <%= submit_tag(_("Search contributions by this person")) %>
+ <% end %>
+ </div>
+ <% end %>
<% if !@xapian_requests.nil? %>
<% if @xapian_requests.results.empty? %>
@@ -143,16 +142,16 @@
<h2 class="foi_results" id="foi_requests"><%= @is_you ? 'Freedom of Information requests made by you' : 'Freedom of Information requests made by this person' %> <%= @match_phrase %>
</h2>
<p><%= @is_you ? _('You have made no Freedom of Information requests using this site.') : _('This person has made no Freedom of Information requests using this site.') %>
- <%= @page_desc %>
+ <%= @page_desc %>
<% end %>
<% else %>
<h2 class="foi_results" id="foi_requests">
<%= @is_you ? n_('Your %d Freedom of Information request', 'Your %d Freedom of Information requests', @xapian_requests.matches_estimated.to_s) % @xapian_requests.matches_estimated.to_s : n_('This person\'s %d Freedom of Information request', 'This person\'s %d Freedom of Information requests', @xapian_requests.matches_estimated.to_s) % @xapian_requests.matches_estimated %>
<!-- matches_estimated <%=@xapian_requests.matches_estimated%> -->
<%= @match_phrase %>
- <%= @page_desc %>
+ <%= @page_desc %>
</h2>
-
+
<% for result in @xapian_requests.results %>
<%= render :partial => 'request/request_listing_via_event', :locals => { :event => result[:model], :info_request => result[:model].info_request } %>
@@ -171,9 +170,9 @@
<% if @xapian_comments.results.empty? %>
<% if @page == 1 %>
<h2><%= @is_you ? _('Your annotations') : _('This person\'s annotations') %>
- <%= @match_phrase %>
- </h2>
- <p><%= _('None made.')%></p>
+ <%= @match_phrase %>
+ </h2>
+ <p><%= _('None made.')%></p>
<% end %>
<% else %>
<h2 id="annotations">