diff options
Diffstat (limited to 'app/controllers')
-rw-r--r-- | app/controllers/admin_controller.rb | 4 | ||||
-rw-r--r-- | app/controllers/admin_request_controller.rb | 2 | ||||
-rw-r--r-- | app/controllers/api_controller.rb | 72 | ||||
-rw-r--r-- | app/controllers/application_controller.rb | 22 | ||||
-rw-r--r-- | app/controllers/request_controller.rb | 44 |
5 files changed, 94 insertions, 50 deletions
diff --git a/app/controllers/admin_controller.rb b/app/controllers/admin_controller.rb index d7933b212..d93e68dab 100644 --- a/app/controllers/admin_controller.rb +++ b/app/controllers/admin_controller.rb @@ -28,6 +28,10 @@ class AdminController < ApplicationController cache_subpath = foi_fragment_cache_all_for_request(info_request) FileUtils.rm_rf(cache_subpath) + # Remove any download zips + download_dir = request_download_zip_dir(info_request) + FileUtils.rm_rf(download_dir) + # Remove the database caches of body / attachment text (the attachment text # one is after privacy rules are applied) info_request.clear_in_database_caches! diff --git a/app/controllers/admin_request_controller.rb b/app/controllers/admin_request_controller.rb index 1de63be59..c7c8d4972 100644 --- a/app/controllers/admin_request_controller.rb +++ b/app/controllers/admin_request_controller.rb @@ -277,7 +277,7 @@ class AdminRequestController < AdminController if params[:incoming_message_id] incoming_message = IncomingMessage.find(params[:incoming_message_id]) - email = incoming_message.from_address + email = incoming_message.from_email name = incoming_message.safe_mail_from || info_request.public_body.name else email = info_request.public_body.request_email diff --git a/app/controllers/api_controller.rb b/app/controllers/api_controller.rb index aa5e85db3..15fb4f5f9 100644 --- a/app/controllers/api_controller.rb +++ b/app/controllers/api_controller.rb @@ -1,30 +1,30 @@ class ApiController < ApplicationController before_filter :check_api_key - + def show_request @request = InfoRequest.find(params[:id]) raise PermissionDenied if @request.public_body_id != @public_body.id - + @request_data = { :id => @request.id, :url => make_url("request", @request.url_title), :title => @request.title, - + :created_at => @request.created_at, :updated_at => @request.updated_at, - + :status => @request.calculate_status, - + :public_body_url => make_url("body", @request.public_body.url_name), :requestor_url => make_url("user", @request.user.url_name), :request_email => @request.incoming_email, - + :request_text => @request.last_event_forming_initial_request.outgoing_message.body, } - + render :json => @request_data end - + def create_request json = ActiveSupport::JSON.decode(params[:request_json]) request = InfoRequest.new( @@ -34,7 +34,7 @@ class ApiController < ApplicationController :external_user_name => json["external_user_name"], :external_url => json["external_url"] ) - + outgoing_message = OutgoingMessage.new( :status => 'ready', :message_type => 'initial_request', @@ -44,7 +44,7 @@ class ApiController < ApplicationController :info_request => request ) request.outgoing_messages << outgoing_message - + # Return an error if the request is invalid # (Can this ever happen?) if !request.valid? @@ -53,7 +53,7 @@ class ApiController < ApplicationController } return end - + # Save the request, and add the corresponding InfoRequestEvent request.save! request.log_event("sent", @@ -62,69 +62,69 @@ class ApiController < ApplicationController :outgoing_message_id => outgoing_message.id, :smtp_message_id => nil ) - + # Return the URL and ID number. render :json => { 'url' => make_url("request", request.url_title), 'id' => request.id } - + end - + def add_correspondence request = InfoRequest.find_by_id(params[:id]) if request.nil? render :json => { "errors" => ["Could not find request #{params[:id]}"] }, :status => 404 return end - + json = ActiveSupport::JSON.decode(params[:correspondence_json]) attachments = params[:attachments] - + direction = json["direction"] body = json["body"] sent_at_str = json["sent_at"] - + errors = [] - + if !request.is_external? render :json => { "errors" => ["Request #{params[:id]} cannot be updated using the API"] }, :status => 500 return end - + if request.public_body_id != @public_body.id render :json => { "errors" => ["You do not own request #{params[:id]}"] }, :status => 500 return end - + if !["request", "response"].include?(direction) errors << "The direction parameter must be 'request' or 'response'" end - + if body.nil? errors << "The 'body' is missing" elsif body.empty? errors << "The 'body' is empty" end - + begin sent_at = Time.iso8601(sent_at_str) rescue ArgumentError errors << "Failed to parse 'sent_at' field as ISO8601 time: #{sent_at_str}" end - + if direction == "request" && !attachments.nil? errors << "You cannot attach files to messages in the 'request' direction" end - + if !errors.empty? render :json => { "errors" => errors }, :status => 500 return end - + if direction == "request" # In the 'request' direction, i.e. what we (Alaveteli) regard as outgoing - + outgoing_message = OutgoingMessage.new( :info_request => request, :status => 'ready', @@ -154,19 +154,19 @@ class ApiController < ApplicationController :filename => filename ) end - + mail = RequestMailer.create_external_response(request, body, sent_at, attachment_hashes) request.receive(mail, mail.encoded, true) end render :json => { 'url' => make_url("request", request.url_title), - } + } end - + def body_request_events feed_type = params[:feed_type] raise PermissionDenied.new("#{@public_body.id} != #{params[:id]}") if @public_body.id != params[:id].to_i - + since_date_str = params[:since_date] if since_date_str.nil? @events = InfoRequestEvent.find_by_sql([ @@ -213,7 +213,7 @@ class ApiController < ApplicationController @event_data = [] @events.each do |event| break if event.id == @since_event_id - + request = event.info_request this_event = { :request_id => request.id, @@ -224,13 +224,13 @@ class ApiController < ApplicationController :request_email => request.incoming_email, :title => request.title, :body => event.outgoing_message.body, - + :user_name => request.user_name, } if request.user this_event[:user_url] = main_url(user_url(request.user)) end - + @event_data.push(this_event) end render :json => @event_data @@ -238,14 +238,14 @@ class ApiController < ApplicationController raise ActiveRecord::RecordNotFound.new("Unrecognised feed type: #{feed_type}") end end - + protected def check_api_key - raise "Missing required parameter 'k'" if params[:k].nil? + raise PermissionDenied.new("Missing required parameter 'k'") if params[:k].nil? @public_body = PublicBody.find_by_api_key(params[:k].gsub(' ', '+')) raise PermissionDenied if @public_body.nil? end - + private def make_url(*args) "http://" + Configuration::domain + "/" + args.join("/") diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index f9649c868..a946526b8 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -54,10 +54,15 @@ class ApplicationController < ActionController::Base end def set_gettext_locale + if Configuration::include_default_locale_in_urls == false + params_locale = params[:locale] ? params[:locale] : I18n.default_locale + else + params_locale = params[:locale] + end if Configuration::use_default_browser_language - requested_locale = params[:locale] || session[:locale] || cookies[:locale] || request.env['HTTP_ACCEPT_LANGUAGE'] || I18n.default_locale + requested_locale = params_locale || session[:locale] || cookies[:locale] || request.env['HTTP_ACCEPT_LANGUAGE'] || I18n.default_locale else - requested_locale = params[:locale] || session[:locale] || cookies[:locale] || I18n.default_locale + requested_locale = params_locale || session[:locale] || cookies[:locale] || I18n.default_locale end requested_locale = FastGettext.best_locale_in(requested_locale) session[:locale] = FastGettext.set_locale(requested_locale) @@ -226,6 +231,19 @@ class ApplicationController < ActionController::Base end end + def request_dirs(info_request) + first_three_digits = info_request.id.to_s()[0..2] + File.join(first_three_digits.to_s, info_request.id.to_s) + end + + def request_download_zip_dir(info_request) + File.join(download_zip_dir, "download", request_dirs(info_request)) + end + + def download_zip_dir() + File.join(Rails.root, '/cache/zips/') + end + # get the local locale def locale_from_params(*args) if params[:show_locale] diff --git a/app/controllers/request_controller.rb b/app/controllers/request_controller.rb index e82491bbe..3e8c0a5f6 100644 --- a/app/controllers/request_controller.rb +++ b/app/controllers/request_controller.rb @@ -139,6 +139,11 @@ class RequestController < ApplicationController short_cache @per_page = 25 @page = (params[:page] || "1").to_i + + # Later pages are very expensive to load + if @page > MAX_RESULTS / PER_PAGE + raise ActiveRecord::RecordNotFound.new("Sorry. No pages after #{MAX_RESULTS / PER_PAGE}.") + end @info_request = InfoRequest.find_by_url_title!(params[:url_title]) raise ActiveRecord::RecordNotFound.new("Request not found") if @info_request.nil? @@ -148,6 +153,8 @@ class RequestController < ApplicationController end @xapian_object = ::ActsAsXapian::Similar.new([InfoRequestEvent], @info_request.info_request_events, :offset => (@page - 1) * @per_page, :limit => @per_page, :collapse_by_prefix => 'request_collapse') + @matches_estimated = @xapian_object.matches_estimated + @show_no_more_than = (@matches_estimated > MAX_RESULTS) ? MAX_RESULTS : @matches_estimated if (@page > 1) @page_desc = " (page " + @page.to_s + ")" @@ -743,6 +750,12 @@ class RequestController < ApplicationController end def get_attachment_as_html + + # The conversion process can generate files in the cache directory that can be served up + # directly by the webserver according to httpd.conf, so don't allow it unless that's OK. + if @files_can_be_cached != true + raise ActiveRecord::RecordNotFound.new("Attachment HTML not found.") + end get_attachment_internal(true) # images made during conversion (e.g. images in PDF files) are put in the cache directory, so @@ -862,22 +875,32 @@ class RequestController < ApplicationController def download_entire_request @locale = self.locale_from_params() PublicBody.with_locale(@locale) do - info_request = InfoRequest.find_by_url_title!(params[:url_title]) + @info_request = InfoRequest.find_by_url_title!(params[:url_title]) + # Test for whole request being hidden or requester-only + if !@info_request.all_can_view? + render :template => 'request/hidden', :status => 410 # gone + return + end if authenticated?( :web => _("To download the zip file"), - :email => _("Then you can download a zip file of {{info_request_title}}.",:info_request_title=>info_request.title), - :email_subject => _("Log in to download a zip file of {{info_request_title}}",:info_request_title=>info_request.title) + :email => _("Then you can download a zip file of {{info_request_title}}.", + :info_request_title=>@info_request.title), + :email_subject => _("Log in to download a zip file of {{info_request_title}}", + :info_request_title=>@info_request.title) ) - updated = Digest::SHA1.hexdigest(info_request.get_last_event.created_at.to_i.to_s + info_request.updated_at.to_i.to_s) - @url_path = "/download/#{updated[0..1]}/#{updated}/#{params[:url_title]}.zip" - file_path = File.expand_path(File.join(File.dirname(__FILE__), '../../cache/zips', @url_path)) + updated = Digest::SHA1.hexdigest(@info_request.get_last_event.created_at.to_i.to_s + @info_request.updated_at.to_i.to_s) + @url_path = File.join("/download", + request_dirs(@info_request), + updated, + "#{params[:url_title]}.zip") + file_path = File.expand_path(File.join(download_zip_dir(), @url_path)) if !File.exists?(file_path) FileUtils.mkdir_p(File.dirname(file_path)) Zip::ZipFile.open(file_path, Zip::ZipFile::CREATE) { |zipfile| convert_command = Configuration::html_to_pdf_command done = false if !convert_command.blank? && File.exists?(convert_command) - url = "http://#{Configuration::domain}#{request_url(info_request)}?print_stylesheet=1" + url = "http://#{Configuration::domain}#{request_url(@info_request)}?print_stylesheet=1" tempfile = Tempfile.new('foihtml2pdf') output = AlaveteliExternalCommand.run(convert_command, url, tempfile.path) if !output.nil? @@ -886,22 +909,21 @@ class RequestController < ApplicationController } done = true else - logger.error("Could not convert info request #{info_request.id} to PDF with command '#{convert_command} #{url} #{tempfile.path}'") + logger.error("Could not convert info request #{@info_request.id} to PDF with command '#{convert_command} #{url} #{tempfile.path}'") end tempfile.close else logger.warn("No HTML -> PDF converter found at #{convert_command}") end if !done - @info_request = info_request - @info_request_events = info_request.info_request_events + @info_request_events = @info_request.info_request_events template = File.read(File.join(File.dirname(__FILE__), "..", "views", "request", "simple_correspondence.rhtml")) output = ERB.new(template).result(binding) zipfile.get_output_stream("correspondence.txt") { |f| f.puts(output) } end - for message in info_request.incoming_messages + for message in @info_request.incoming_messages attachments = message.get_attachments_for_display for attachment in attachments filename = "#{attachment.url_part_number}_#{attachment.display_filename}" |