diff options
Diffstat (limited to 'app/controllers')
20 files changed, 444 insertions, 334 deletions
diff --git a/app/controllers/admin_censor_rule_controller.rb b/app/controllers/admin_censor_rule_controller.rb index 68ca57510..3387fd832 100644 --- a/app/controllers/admin_censor_rule_controller.rb +++ b/app/controllers/admin_censor_rule_controller.rb @@ -5,11 +5,15 @@ # Email: hello@mysociety.org; WWW: http://www.mysociety.org/ class AdminCensorRuleController < AdminController + + before_filter :set_editor, :only => [:create, :update] + before_filter :find_and_check_rule, :only => [:edit, :update, :destroy] + def new - if params[:info_request_id] - @info_request = InfoRequest.find(params[:info_request_id]) + if params[:request_id] + @info_request = InfoRequest.find(params[:request_id]) @censor_rule = @info_request.censor_rules.build - @form_url = admin_info_request_censor_rules_path(@info_request) + @form_url = admin_request_censor_rules_path(@info_request) end if params[:user_id] @@ -17,18 +21,13 @@ class AdminCensorRuleController < AdminController @censor_rule = @censor_user.censor_rules.build @form_url = admin_user_censor_rules_path(@censor_user) end - - @censor_rule ||= CensorRule.new - @form_url ||= admin_rule_create_path end def create - params[:censor_rule][:last_edit_editor] = admin_current_user - - if params[:info_request_id] - @info_request = InfoRequest.find(params[:info_request_id]) + if params[:request_id] + @info_request = InfoRequest.find(params[:request_id]) @censor_rule = @info_request.censor_rules.build(params[:censor_rule]) - @form_url = admin_info_request_censor_rules_path(@info_request) + @form_url = admin_request_censor_rules_path(@info_request) end if params[:user_id] @@ -37,26 +36,16 @@ class AdminCensorRuleController < AdminController @form_url = admin_user_censor_rules_path(@censor_user) end - @censor_rule ||= CensorRule.new(params[:censor_rule]) - @form_url ||= admin_rule_create_path - if @censor_rule.save - if !@censor_rule.info_request.nil? - expire_for_request(@censor_rule.info_request) - end - - if !@censor_rule.user.nil? - expire_requests_for_user(@censor_rule.user) - end flash[:notice] = 'CensorRule was successfully created.' - if !@censor_rule.info_request.nil? - redirect_to admin_request_show_url(@censor_rule.info_request) - elsif !@censor_rule.user.nil? - redirect_to admin_user_show_url(@censor_rule.user) - else - raise "internal error" + if @censor_rule.info_request + expire_for_request(@censor_rule.info_request) + redirect_to admin_request_url(@censor_rule.info_request) + elsif @censor_rule.user + expire_requests_for_user(@censor_rule.user) + redirect_to admin_user_url(@censor_rule.user) end else render :action => 'new' @@ -64,63 +53,55 @@ class AdminCensorRuleController < AdminController end def edit - @censor_rule = CensorRule.find(params[:id]) end def update - params[:censor_rule][:last_edit_editor] = admin_current_user - @censor_rule = CensorRule.find(params[:id]) - if @censor_rule.update_attributes(params[:censor_rule]) - unless @censor_rule.info_request.nil? - expire_for_request(@censor_rule.info_request) - end - - unless @censor_rule.user.nil? - expire_requests_for_user(@censor_rule.user) - end flash[:notice] = 'CensorRule was successfully updated.' - if !@censor_rule.info_request.nil? - redirect_to admin_request_show_url(@censor_rule.info_request) - elsif !@censor_rule.user.nil? - redirect_to admin_user_show_url(@censor_rule.user) - else - raise "internal error" + if @censor_rule.info_request + expire_for_request(@censor_rule.info_request) + redirect_to admin_request_url(@censor_rule.info_request) + elsif @censor_rule.user + expire_requests_for_user(@censor_rule.user) + redirect_to admin_user_url(@censor_rule.user) end + else render :action => 'edit' end end def destroy - @censor_rule = CensorRule.find(params[:censor_rule_id]) info_request = @censor_rule.info_request user = @censor_rule.user - @censor_rule.destroy - unless info_request.nil? - expire_for_request(info_request) - end - - unless user.nil? - expire_requests_for_user(user) - end - flash[:notice] = "CensorRule was successfully destroyed." - if !info_request.nil? - redirect_to admin_request_show_url(info_request) - elsif !user.nil? - redirect_to admin_user_show_url(user) - else - raise "internal error" + if info_request + expire_for_request(info_request) + redirect_to admin_request_url(info_request) + elsif user + expire_requests_for_user(user) if user + redirect_to admin_user_url(user) end + end private + def set_editor + params[:censor_rule][:last_edit_editor] = admin_current_user + end + + def find_and_check_rule + @censor_rule = CensorRule.find(params[:id]) + unless (@censor_rule.user || @censor_rule.info_request) + flash[:notice] = 'Only user and request censor rules can be edited' + redirect_to admin_general_index_path + end + end end diff --git a/app/controllers/admin_comment_controller.rb b/app/controllers/admin_comment_controller.rb new file mode 100644 index 000000000..0aafb122a --- /dev/null +++ b/app/controllers/admin_comment_controller.rb @@ -0,0 +1,36 @@ +# app/controllers/admin_comment_controller.rb: +# Controller for editing comments from the admin interface. +# +# Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved. +# Email: hello@mysociety.org; WWW: http://www.mysociety.org/ + +class AdminCommentController < AdminController + + def edit + @comment = Comment.find(params[:id]) + end + + def update + @comment = Comment.find(params[:id]) + + old_body = @comment.body + old_visible = @comment.visible + @comment.visible = params[:comment][:visible] == "true" ? true : false + + if @comment.update_attributes(params[:comment]) + @comment.info_request.log_event("edit_comment", + { :comment_id => @comment.id, + :editor => admin_current_user(), + :old_body => old_body, + :body => @comment.body, + :old_visible => old_visible, + :visible => @comment.visible, + }) + flash[:notice] = 'Comment successfully updated.' + redirect_to admin_request_url(@comment.info_request) + else + render :action => 'edit' + end + end + +end diff --git a/app/controllers/admin_controller.rb b/app/controllers/admin_controller.rb index 3bf40b8f9..7760c372b 100644 --- a/app/controllers/admin_controller.rb +++ b/app/controllers/admin_controller.rb @@ -9,7 +9,6 @@ require 'fileutils' class AdminController < ApplicationController layout "admin" before_filter :authenticate - protect_from_forgery # See ActionController::RequestForgeryProtection for details # action to take if expecting an authenticity token and one isn't received def handle_unverified_request diff --git a/app/controllers/admin_holiday_imports_controller.rb b/app/controllers/admin_holiday_imports_controller.rb new file mode 100644 index 000000000..8596936f0 --- /dev/null +++ b/app/controllers/admin_holiday_imports_controller.rb @@ -0,0 +1,28 @@ +class AdminHolidayImportsController < AdminController + + def new + @holiday_import = HolidayImport.new(holiday_import_params) + @holiday_import.populate if @holiday_import.valid? + end + + def create + @holiday_import = HolidayImport.new(holiday_import_params) + if @holiday_import.save + notice = "Holidays successfully imported" + redirect_to admin_holidays_path, :notice => notice + else + render :new + end + end + + private + + def holiday_import_params(key = :holiday_import) + if params[key] + params[key].slice(:holidays_attributes, :start_year, :end_year, :source, :ical_feed_url) + else + {} + end + end + +end diff --git a/app/controllers/admin_holidays_controller.rb b/app/controllers/admin_holidays_controller.rb new file mode 100644 index 000000000..9177ebd44 --- /dev/null +++ b/app/controllers/admin_holidays_controller.rb @@ -0,0 +1,67 @@ +class AdminHolidaysController < AdminController + + def index + get_all_holidays + end + + def new + @holiday = Holiday.new + if request.xhr? + render :partial => 'new_form', :locals => { :holiday => @holiday } + else + render :action => 'new' + end + end + + def create + @holiday = Holiday.new(holiday_params) + if @holiday.save + notice = "Holiday successfully created." + redirect_to admin_holidays_path, :notice => notice + else + render :new + end + end + + def edit + @holiday = Holiday.find(params[:id]) + if request.xhr? + render :partial => 'edit_form' + else + render :action => 'edit' + end + end + + def update + @holiday = Holiday.find(params[:id]) + if @holiday.update_attributes(holiday_params) + flash[:notice] = 'Holiday successfully updated.' + redirect_to admin_holidays_path + else + render :edit + end + end + + def destroy + @holiday = Holiday.find(params[:id]) + @holiday.destroy + notice = "Holiday successfully destroyed" + redirect_to admin_holidays_path, :notice => notice + end + + private + + def get_all_holidays + @holidays_by_year = Holiday.all.group_by { |holiday| holiday.day.year } + @years = @holidays_by_year.keys.sort.reverse + end + + def holiday_params(key = :holiday) + if params[key] + params[key].slice(:description, 'day(1i)', 'day(2i)', 'day(3i)') + else + {} + end + end + +end diff --git a/app/controllers/admin_incoming_message_controller.rb b/app/controllers/admin_incoming_message_controller.rb index 6b50d0e36..bc653bf53 100644 --- a/app/controllers/admin_incoming_message_controller.rb +++ b/app/controllers/admin_incoming_message_controller.rb @@ -20,14 +20,14 @@ class AdminIncomingMessageController < AdminController :prominence_reason => @incoming_message.prominence_reason) expire_for_request(@incoming_message.info_request) flash[:notice] = 'Incoming message successfully updated.' - redirect_to admin_request_show_url(@incoming_message.info_request) + redirect_to admin_request_url(@incoming_message.info_request) else render :action => 'edit' end end def destroy - @incoming_message = IncomingMessage.find(params[:incoming_message_id]) + @incoming_message = IncomingMessage.find(params[:id]) @info_request = @incoming_message.info_request incoming_message_id = @incoming_message.id @@ -37,11 +37,11 @@ class AdminIncomingMessageController < AdminController # expire cached files expire_for_request(@info_request) flash[:notice] = 'Incoming message successfully destroyed.' - redirect_to admin_request_show_url(@info_request) + redirect_to admin_request_url(@info_request) end def redeliver - incoming_message = IncomingMessage.find(params[:redeliver_incoming_message_id]) + incoming_message = IncomingMessage.find(params[:id]) message_ids = params[:url_title].split(",").each {|x| x.strip} previous_request = incoming_message.info_request destination_request = nil @@ -54,7 +54,7 @@ class AdminIncomingMessageController < AdminController end if destination_request.nil? flash[:error] = "Failed to find destination request '" + m + "'" - return redirect_to admin_request_show_url(previous_request) + return redirect_to admin_request_url(previous_request) end raw_email_data = incoming_message.raw_email.data @@ -74,7 +74,7 @@ class AdminIncomingMessageController < AdminController expire_for_request(previous_request) incoming_message.fully_destroy end - redirect_to admin_request_show_url(destination_request) + redirect_to admin_request_url(destination_request) end end diff --git a/app/controllers/admin_info_request_event_controller.rb b/app/controllers/admin_info_request_event_controller.rb new file mode 100644 index 000000000..17d147582 --- /dev/null +++ b/app/controllers/admin_info_request_event_controller.rb @@ -0,0 +1,24 @@ +# app/controllers/admin_info_request_event_controller.rb: +# Controller for FOI request event manipulation from the admin interface. +# +# Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved. +# Email: hello@mysociety.org; WWW: http://www.mysociety.org/ + +class AdminInfoRequestEventController < AdminController + + # used so due dates get fixed + def update + @info_request_event = InfoRequestEvent.find(params[:id]) + if @info_request_event.event_type != 'response' + raise Exception("can only mark responses as requires clarification") + end + @info_request_event.described_state = 'waiting_clarification' + @info_request_event.calculated_state = 'waiting_clarification' + # TODO: deliberately don't update described_at so doesn't reenter search? + @info_request_event.save! + + flash[:notice] = "Old response marked as having been a clarification" + redirect_to admin_request_url(@info_request_event.info_request) + end + +end diff --git a/app/controllers/admin_outgoing_message_controller.rb b/app/controllers/admin_outgoing_message_controller.rb index ec0981677..2ee811dc0 100644 --- a/app/controllers/admin_outgoing_message_controller.rb +++ b/app/controllers/admin_outgoing_message_controller.rb @@ -5,7 +5,7 @@ class AdminOutgoingMessageController < AdminController end def destroy - @outgoing_message = OutgoingMessage.find(params[:outgoing_message_id]) + @outgoing_message = OutgoingMessage.find(params[:id]) @info_request = @outgoing_message.info_request outgoing_message_id = @outgoing_message.id @@ -14,7 +14,7 @@ class AdminOutgoingMessageController < AdminController { :editor => admin_current_user(), :deleted_outgoing_message_id => outgoing_message_id }) flash[:notice] = 'Outgoing message successfully destroyed.' - redirect_to admin_request_show_url(@info_request) + redirect_to admin_request_url(@info_request) end def update @@ -38,10 +38,41 @@ class AdminOutgoingMessageController < AdminController :prominence_reason => @outgoing_message.prominence_reason }) flash[:notice] = 'Outgoing message successfully updated.' expire_for_request(@outgoing_message.info_request) - redirect_to admin_request_show_url(@outgoing_message.info_request) + redirect_to admin_request_url(@outgoing_message.info_request) else render :action => 'edit' end end + def resend + @outgoing_message = OutgoingMessage.find(params[:id]) + @outgoing_message.prepare_message_for_resend + + mail_message = case @outgoing_message.message_type + when 'initial_request' + OutgoingMailer.initial_request( + @outgoing_message.info_request, + @outgoing_message + ).deliver + when 'followup' + OutgoingMailer.followup( + @outgoing_message.info_request, + @outgoing_message, + @outgoing_message.incoming_message_followup + ).deliver + else + raise "Message id #{id} has type '#{message_type}' which cannot be resent" + end + + @outgoing_message.record_email_delivery( + mail_message.to_addrs.join(', '), + mail_message.message_id, + 'resent' + ) + + flash[:notice] = "Outgoing message resent" + redirect_to admin_request_url(@outgoing_message.info_request) + end + + end diff --git a/app/controllers/admin_public_body_controller.rb b/app/controllers/admin_public_body_controller.rb index f7a80476c..cfb6f240d 100644 --- a/app/controllers/admin_public_body_controller.rb +++ b/app/controllers/admin_public_body_controller.rb @@ -5,69 +5,9 @@ # Email: hello@mysociety.org; WWW: http://www.mysociety.org/ class AdminPublicBodyController < AdminController - def index - list - render :action => 'list' - end - - def _lookup_query_internal - @locale = self.locale_from_params() - underscore_locale = @locale.gsub '-', '_' - I18n.with_locale(@locale) do - @query = params[:query] - if @query == "" - @query = nil - end - @page = params[:page] - if @page == "" - @page = nil - end - @public_bodies = PublicBody.joins(:translations).where(@query.nil? ? "public_body_translations.locale = '#{underscore_locale}'" : - ["(lower(public_body_translations.name) like lower('%'||?||'%') or - lower(public_body_translations.short_name) like lower('%'||?||'%') or - lower(public_body_translations.request_email) like lower('%'||?||'%' )) AND (public_body_translations.locale = '#{underscore_locale}')", @query, @query, @query]).paginate :order => "public_body_translations.name", :page => @page, :per_page => 100 - end - @public_bodies_by_tag = PublicBody.find_by_tag(@query) - end - def list - self._lookup_query_internal - end - - def mass_tag_add - self._lookup_query_internal - - if params[:new_tag] and params[:new_tag] != "" - if params[:table_name] == 'exact' - bodies = @public_bodies_by_tag - elsif params[:table_name] == 'substring' - bodies = @public_bodies - else - raise "Unknown table_name " + params[:table_name] - end - for body in bodies - body.add_tag_if_not_already_present(params[:new_tag]) - end - flash[:notice] = "Added tag to table of bodies." - end - - redirect_to admin_body_list_url(:query => @query, :page => @page) - end - - def missing_scheme - # There might be a way to do this in ActiveRecord, but I can't find it - @public_bodies = PublicBody.find_by_sql(" - SELECT a.id, a.name, a.url_name, COUNT(*) AS howmany - FROM public_bodies a JOIN info_requests r ON a.id = r.public_body_id - WHERE a.publication_scheme = '' - GROUP BY a.id, a.name, a.url_name - ORDER BY howmany DESC - LIMIT 20 - ") - @stats = { - "total" => PublicBody.count, - "entered" => PublicBody.count(:conditions => "publication_scheme != ''") - } + def index + lookup_query end def show @@ -111,7 +51,7 @@ class AdminPublicBodyController < AdminController @change_request.send_response(params[:subject], response_text) end flash[:notice] = 'PublicBody was successfully created.' - redirect_to admin_body_show_url(@public_body) + redirect_to admin_body_url(@public_body) else render :action => 'new' end @@ -147,7 +87,7 @@ class AdminPublicBodyController < AdminController @change_request.send_response(params[:subject], params[:response]) end flash[:notice] = 'PublicBody was successfully updated.' - redirect_to admin_body_show_url(@public_body) + redirect_to admin_body_url(@public_body) else render :action => 'edit' end @@ -161,17 +101,53 @@ class AdminPublicBodyController < AdminController if public_body.info_requests.size > 0 flash[:notice] = "There are requests associated with the authority, so can't destroy it" - redirect_to admin_body_show_url(public_body) + redirect_to admin_body_url(public_body) return end public_body.tag_string = "" public_body.destroy flash[:notice] = "PublicBody was successfully destroyed." - redirect_to admin_body_list_url + redirect_to admin_bodies_url end end + def mass_tag_add + lookup_query + + if params[:new_tag] and params[:new_tag] != "" + if params[:table_name] == 'exact' + bodies = @public_bodies_by_tag + elsif params[:table_name] == 'substring' + bodies = @public_bodies + else + raise "Unknown table_name " + params[:table_name] + end + for body in bodies + body.add_tag_if_not_already_present(params[:new_tag]) + end + flash[:notice] = "Added tag to table of bodies." + end + + redirect_to admin_bodies_url(:query => @query, :page => @page) + end + + def missing_scheme + # There might be a way to do this in ActiveRecord, but I can't find it + @public_bodies = PublicBody.find_by_sql(" + SELECT a.id, a.name, a.url_name, COUNT(*) AS howmany + FROM public_bodies a JOIN info_requests r ON a.id = r.public_body_id + WHERE a.publication_scheme = '' + GROUP BY a.id, a.name, a.url_name + ORDER BY howmany DESC + LIMIT 20 + ") + @stats = { + "total" => PublicBody.count, + "entered" => PublicBody.count(:conditions => "publication_scheme != ''") + } + end + def import_csv @notes = "" @errors = "" @@ -251,4 +227,24 @@ class AdminPublicBodyController < AdminController return csv_contents end + def lookup_query + @locale = self.locale_from_params() + underscore_locale = @locale.gsub '-', '_' + I18n.with_locale(@locale) do + @query = params[:query] + if @query == "" + @query = nil + end + @page = params[:page] + if @page == "" + @page = nil + end + @public_bodies = PublicBody.joins(:translations).where(@query.nil? ? "public_body_translations.locale = '#{underscore_locale}'" : + ["(lower(public_body_translations.name) like lower('%'||?||'%') or + lower(public_body_translations.short_name) like lower('%'||?||'%') or + lower(public_body_translations.request_email) like lower('%'||?||'%' )) AND (public_body_translations.locale = '#{underscore_locale}')", @query, @query, @query]).paginate :order => "public_body_translations.name", :page => @page, :per_page => 100 + end + @public_bodies_by_tag = PublicBody.find_by_tag(@query) + end + end diff --git a/app/controllers/admin_raw_email_controller.rb b/app/controllers/admin_raw_email_controller.rb new file mode 100644 index 000000000..1b3ee2871 --- /dev/null +++ b/app/controllers/admin_raw_email_controller.rb @@ -0,0 +1,45 @@ +# app/controllers/admin_raw_email_controller.rb: +# Controller for managing raw emails from the admin interface. +# +# Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved. +# Email: hello@mysociety.org; WWW: http://www.mysociety.org/ + +class AdminRawEmailController < AdminController + + def show + @raw_email = RawEmail.find(params[:id]) + respond_to do |format| + format.html do + # For the holding pen, try to guess where it should be ... + @holding_pen = false + if (@raw_email.incoming_message.info_request == InfoRequest.holding_pen_request && !@raw_email.incoming_message.empty_from_field?) + @holding_pen = true + + # 1. Use domain of email to try and guess which public body it + # is associated with, so we can display that. + email = @raw_email.incoming_message.from_email + domain = PublicBody.extract_domain_from_email(email) + + if domain.nil? + @public_bodies = [] + else + @public_bodies = PublicBody.find(:all, :order => "name", + :conditions => [ "lower(request_email) like lower('%'||?||'%')", domain ]) + end + + # 2. Match the email address in the message without matching the hash + @info_requests = InfoRequest.guess_by_incoming_email(@raw_email.incoming_message) + + # 3. Give a reason why it's in the holding pen + last_event = InfoRequestEvent.find_by_incoming_message_id(@raw_email.incoming_message.id) + @rejected_reason = last_event.params[:rejected_reason] || "unknown reason" + end + end + format.text do + response.content_type = 'message/rfc822' + render :text => @raw_email.data + end + end + end + +end diff --git a/app/controllers/admin_request_controller.rb b/app/controllers/admin_request_controller.rb index 8f023bf12..1e083f57e 100644 --- a/app/controllers/admin_request_controller.rb +++ b/app/controllers/admin_request_controller.rb @@ -4,15 +4,9 @@ # Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved. # Email: hello@mysociety.org; WWW: http://www.mysociety.org/ -require 'ostruct' - class AdminRequestController < AdminController - def index - list - render :action => 'list' - end - def list + def index @query = params[:query] if @query info_requests = InfoRequest.where(["lower(title) like lower('%'||?||'%')", @query]) @@ -35,36 +29,6 @@ class AdminRequestController < AdminController :locals => vars_for_explanation) end - def resend - @outgoing_message = OutgoingMessage.find(params[:outgoing_message_id]) - @outgoing_message.prepare_message_for_resend - - mail_message = case @outgoing_message.message_type - when 'initial_request' - OutgoingMailer.initial_request( - @outgoing_message.info_request, - @outgoing_message - ).deliver - when 'followup' - OutgoingMailer.followup( - @outgoing_message.info_request, - @outgoing_message, - @outgoing_message.incoming_message_followup - ).deliver - else - raise "Message id #{id} has type '#{message_type}' which cannot be resent" - end - - @outgoing_message.record_email_delivery( - mail_message.to_addrs.join(', '), - mail_message.message_id, - 'resent' - ) - - flash[:notice] = "Outgoing message resent" - redirect_to admin_request_show_url(@outgoing_message.info_request) - end - def edit @info_request = InfoRequest.find(params[:id]) end @@ -108,13 +72,13 @@ class AdminRequestController < AdminController # expire cached files expire_for_request(@info_request) flash[:notice] = 'Request successfully updated.' - redirect_to admin_request_show_url(@info_request) + redirect_to admin_request_url(@info_request) else render :action => 'edit' end end - def fully_destroy + def destroy @info_request = InfoRequest.find(params[:id]) user = @info_request.user @@ -125,36 +89,12 @@ class AdminRequestController < AdminController expire_for_request(@info_request) email = user.try(:email) ? user.email : 'This request is external so has no associated user' flash[:notice] = "Request #{ url_title } has been completely destroyed. Email of user who made request: #{ email }" - redirect_to admin_request_list_url - end - - def edit_comment - @comment = Comment.find(params[:id]) - end - - def update_comment - @comment = Comment.find(params[:id]) - - old_body = @comment.body - old_visible = @comment.visible - @comment.visible = params[:comment][:visible] == "true" ? true : false - - if @comment.update_attributes(params[:comment]) - @comment.info_request.log_event("edit_comment", - { :comment_id => @comment.id, :editor => admin_current_user(), - :old_body => old_body, :body => @comment.body, - :old_visible => old_visible, :visible => @comment.visible, - }) - flash[:notice] = 'Comment successfully updated.' - redirect_to admin_request_show_url(@comment.info_request) - else - render :action => 'edit_comment' - end + redirect_to admin_requests_url end # change user or public body of a request magically - def move_request - info_request = InfoRequest.find(params[:info_request_id]) + def move + info_request = InfoRequest.find(params[:id]) if params[:commit] == 'Move request to user' && !params[:user_url_name].blank? old_user = info_request.user destination_user = User.find_by_url_name(params[:user_url_name]) @@ -172,7 +112,7 @@ class AdminRequestController < AdminController info_request.reindex_request_events flash[:notice] = "Message has been moved to new user" end - redirect_to admin_request_show_url(info_request) + redirect_to admin_request_url(info_request) elsif params[:commit] == 'Move request to authority' && !params[:public_body_url_name].blank? old_public_body = info_request.public_body destination_public_body = PublicBody.find_by_url_name(params[:public_body_url_name]) @@ -191,10 +131,10 @@ class AdminRequestController < AdminController flash[:notice] = "Request has been moved to new body" end - redirect_to admin_request_show_url(info_request) + redirect_to admin_request_url(info_request) else flash[:error] = "Please enter the user or authority to move the request to" - redirect_to admin_request_show_url(info_request) + redirect_to admin_request_url(info_request) end end @@ -218,7 +158,7 @@ class AdminRequestController < AdminController if !info_request.public_body.is_foi_officer?(user) flash[:notice] = user.email + " is not an email at the domain @" + info_request.public_body.foi_officer_domain_required + ", so won't be able to upload." - redirect_to admin_request_show_url(info_request) + redirect_to admin_request_url(info_request) return end @@ -230,61 +170,11 @@ class AdminRequestController < AdminController post_redirect.save! url = confirm_url(:email_token => post_redirect.email_token) - flash[:notice] = ("Send \"#{name}\" <<a href=\"mailto:#{email}\">#{email}</a>> this URL: <a href=\"#{url}\">#{url}</a> - it will log them in and let them upload a response to this request.").html_safe - redirect_to admin_request_show_url(info_request) - end - - def show_raw_email - @raw_email = RawEmail.find(params[:id]) - # For the holding pen, try to guess where it should be ... - @holding_pen = false - if (@raw_email.incoming_message.info_request == InfoRequest.holding_pen_request && !@raw_email.incoming_message.empty_from_field?) - @holding_pen = true - - # 1. Use domain of email to try and guess which public body it - # is associated with, so we can display that. - email = @raw_email.incoming_message.from_email - domain = PublicBody.extract_domain_from_email(email) - - if domain.nil? - @public_bodies = [] - else - @public_bodies = PublicBody.find(:all, :order => "name", - :conditions => [ "lower(request_email) like lower('%'||?||'%')", domain ]) - end - - # 2. Match the email address in the message without matching the hash - @info_requests = InfoRequest.guess_by_incoming_email(@raw_email.incoming_message) - - # 3. Give a reason why it's in the holding pen - last_event = InfoRequestEvent.find_by_incoming_message_id(@raw_email.incoming_message.id) - @rejected_reason = last_event.params[:rejected_reason] || "unknown reason" - end - end - - def download_raw_email - @raw_email = RawEmail.find(params[:id]) - - response.content_type = 'message/rfc822' - render :text => @raw_email.data - end - - # used so due dates get fixed - def mark_event_as_clarification - info_request_event = InfoRequestEvent.find(params[:info_request_event_id]) - if info_request_event.event_type != 'response' - raise Exception("can only mark responses as requires clarification") - end - info_request_event.described_state = 'waiting_clarification' - info_request_event.calculated_state = 'waiting_clarification' - # TODO: deliberately don't update described_at so doesn't reenter search? - info_request_event.save! - - flash[:notice] = "Old response marked as having been a clarification" - redirect_to admin_request_show_url(info_request_event.info_request) + flash[:notice] = ("Send \"#{CGI.escapeHTML(name)}\" <<a href=\"mailto:#{email}\">#{email}</a>> this URL: <a href=\"#{url}\">#{url}</a> - it will log them in and let them upload a response to this request.").html_safe + redirect_to admin_request_url(info_request) end - def hide_request + def hide ActiveRecord::Base.transaction do subject = params[:subject] explanation = params[:explanation] @@ -314,7 +204,7 @@ class AdminRequestController < AdminController end # expire cached files expire_for_request(info_request) - redirect_to admin_request_show_url(info_request) + redirect_to admin_request_url(info_request) end end diff --git a/app/controllers/admin_track_controller.rb b/app/controllers/admin_track_controller.rb index 085c9c6cc..63ee5c12e 100644 --- a/app/controllers/admin_track_controller.rb +++ b/app/controllers/admin_track_controller.rb @@ -5,7 +5,8 @@ # Email: hello@mysociety.org; WWW: http://www.mysociety.org/ class AdminTrackController < AdminController - def list + + def index @query = params[:query] if @query track_things = TrackThing.where(["lower(track_query) like lower('%'||?||'%')", @query]) @@ -13,7 +14,14 @@ class AdminTrackController < AdminController track_things = TrackThing end @admin_tracks = track_things.paginate :order => "created_at desc", :page => params[:page], :per_page => 100 - @popular = ActiveRecord::Base.connection.select_all("select count(*) as count, title, info_request_id from track_things join info_requests on info_request_id = info_requests.id where info_request_id is not null group by info_request_id, title order by count desc limit 10;") + @popular = ActiveRecord::Base.connection.select_all("select count(*) as count, title, info_request_id from track_things join info_requests on info_request_id = info_requests.id where info_request_id is not null group by info_request_id, title order by count desc limit 10;") + end + + def destroy + track_thing = TrackThing.find(params[:id].to_i) + track_thing.destroy + flash[:notice] = 'Track destroyed' + redirect_to admin_user_url(track_thing.tracking_user) end private diff --git a/app/controllers/admin_user_controller.rb b/app/controllers/admin_user_controller.rb index a6438e151..7ef461594 100644 --- a/app/controllers/admin_user_controller.rb +++ b/app/controllers/admin_user_controller.rb @@ -5,12 +5,8 @@ # Email: hello@mysociety.org; WWW: http://www.mysociety.org/ class AdminUserController < AdminController - def index - list - render :action => 'list' - end - def list + def index @query = params[:query] if @query users = User.where(["lower(name) like lower('%'||?||'%') or @@ -21,20 +17,11 @@ class AdminUserController < AdminController @admin_users = users.paginate :order => "name", :page => params[:page], :per_page => 100 end - def list_banned - @banned_users = User.paginate :order => "name", :page => params[:page], :per_page => 100, - :conditions => ["ban_text <> ''"] - end - def show # Don't use @user as that is any logged in user @admin_user = User.find(params[:id]) end - def show_bounce_message - @admin_user = User.find(params[:id]) - end - def edit @admin_user = User.find(params[:id]) end @@ -53,17 +40,19 @@ class AdminUserController < AdminController if @admin_user.valid? @admin_user.save! flash[:notice] = 'User successfully updated.' - redirect_to admin_user_show_url(@admin_user) + redirect_to admin_user_url(@admin_user) else render :action => 'edit' end end - def destroy_track - track_thing = TrackThing.find(params[:track_id].to_i) - track_thing.destroy - flash[:notice] = 'Track destroyed' - redirect_to admin_user_show_url(track_thing.tracking_user) + def banned + @banned_users = User.paginate :order => "name", :page => params[:page], :per_page => 100, + :conditions => ["ban_text <> ''"] + end + + def show_bounce_message + @admin_user = User.find(params[:id]) end def clear_bounce @@ -71,7 +60,7 @@ class AdminUserController < AdminController user.email_bounced_at = nil user.email_bounce_message = "" user.save! - redirect_to admin_user_show_url(user) + redirect_to admin_user_url(user) end def login_as @@ -87,16 +76,12 @@ class AdminUserController < AdminController def clear_profile_photo @admin_user = User.find(params[:id]) - if !request.post? - raise "Can only clear profile photo from POST request" - end - if @admin_user.profile_photo @admin_user.profile_photo.destroy end flash[:notice] = "Profile photo cleared" - redirect_to admin_user_show_url(@admin_user) + redirect_to admin_user_url(@admin_user) end def modify_comment_visibility diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 4d3f40d40..dbd879a1c 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -14,9 +14,14 @@ class ApplicationController < ActionController::Base end class RouteNotFound < StandardError end + protect_from_forgery + # assign our own handler method for non-local exceptions rescue_from Exception, :with => :render_exception + # Add some security-related headers (see config/initializers/secure_headers.rb) + ensure_security_headers + # Standard headers, footers and navigation for whole site layout "default" include FastGettext::Translation # make functions like _, n_, N_ etc available) @@ -27,6 +32,8 @@ class ApplicationController < ActionController::Base before_filter :check_in_post_redirect before_filter :session_remember_me before_filter :set_vary_header + before_filter :validate_session_timestamp + after_filter :persist_session_timestamp def set_vary_header response.headers['Vary'] = 'Cookie' @@ -118,6 +125,29 @@ class ApplicationController < ActionController::Base end end + # Set a TTL for non "remember me" sessions so that the cookie + # is not replayable forever + SESSION_TTL = 3.hours + def validate_session_timestamp + if session[:user_id] && session.key?(:ttl) && session[:ttl] < SESSION_TTL.ago + clear_session_credentials + redirect_to signin_path + end + end + + def persist_session_timestamp + session[:ttl] = Time.now if session[:user_id] && !session[:remember_me] + end + + # Logout form + def clear_session_credentials + session[:user_id] = nil + session[:user_circumstance] = nil + session[:remember_me] = false + session[:using_admin] = nil + session[:admin_name] = nil + end + def render_exception(exception) # In development or the admin interface let Rails handle the exception # with its stack trace templates diff --git a/app/controllers/comment_controller.rb b/app/controllers/comment_controller.rb index 2c0037577..890e9faaa 100644 --- a/app/controllers/comment_controller.rb +++ b/app/controllers/comment_controller.rb @@ -10,7 +10,6 @@ class CommentController < ApplicationController before_filter :create_track_thing, :only => [ :new ] before_filter :reject_unless_comments_allowed, :only => [ :new ] before_filter :reject_if_user_banned, :only => [ :new ] - protect_from_forgery :only => [ :new ] def new if params[:comment] diff --git a/app/controllers/public_body_controller.rb b/app/controllers/public_body_controller.rb index e64644a1b..2e540d198 100644 --- a/app/controllers/public_body_controller.rb +++ b/app/controllers/public_body_controller.rb @@ -55,6 +55,8 @@ class PublicBodyController < ApplicationController @xapian_requests = nil end + flash.keep(:search_params) + @track_thing = TrackThing.create_track_for_public_body(@public_body) @feed_autodetect = [ { :url => do_track_url(@track_thing, 'feed'), :title => @track_thing.params[:title_in_rss], :has_json => true } ] @@ -349,6 +351,7 @@ class PublicBodyController < ApplicationController # Since acts_as_xapian doesn't support the Partial match flag, we work around it # by making the last work a wildcard, which is quite the same query = params[:query] + flash[:search_params] = params.slice(:query, :bodies, :page) @xapian_requests = perform_search_typeahead(query, PublicBody) render :partial => "public_body/search_ahead" end diff --git a/app/controllers/request_controller.rb b/app/controllers/request_controller.rb index a334abcb7..081c14d7f 100644 --- a/app/controllers/request_controller.rb +++ b/app/controllers/request_controller.rb @@ -10,7 +10,6 @@ require 'open-uri' class RequestController < ApplicationController before_filter :check_read_only, :only => [ :new, :show_response, :describe_state, :upload_response ] - protect_from_forgery :only => [ :new, :show_response, :describe_state, :upload_response ] # See ActionController::RequestForgeryProtection for details before_filter :check_batch_requests_and_user_allowed, :only => [ :select_authorities, :new_batch ] MAX_RESULTS = 500 PER_PAGE = 25 @@ -38,6 +37,7 @@ class RequestController < ApplicationController end if !params[:query].nil? query = params[:query] + flash[:search_params] = params.slice(:query, :bodies, :page) @xapian_requests = perform_search_typeahead(query, PublicBody) end medium_cache @@ -124,7 +124,6 @@ class RequestController < ApplicationController @track_thing = TrackThing.create_track_for_request(@info_request) @feed_autodetect = [ { :url => do_track_url(@track_thing, 'feed'), :title => @track_thing.params[:title_in_rss], :has_json => true } ] - respond_to do |format| format.html { @has_json = true; render :template => 'request/show'} format.json { render :json => @info_request.json_for_api(true) } @@ -246,13 +245,8 @@ class RequestController < ApplicationController :body => params[:outgoing_message][:body], :public_bodies => @public_bodies, :user => authenticated_user) - flash[:notice] = _("<p>Your {{law_used_full}} requests will be <strong>sent</strong> shortly!</p> - <p><strong>We will email you</strong> when they have been sent. - We will also email you when there is a response to any of them, or after {{late_number_of_days}} working days if the authorities still haven't - replied by then.</p> - <p>If you write about these requests (for example in a forum or a blog) please link to this page.</p>", - :law_used_full=>@info_request.law_used_full, - :late_number_of_days => AlaveteliConfiguration::reply_late_after_days) + + flash[:batch_sent] = true redirect_to info_request_batch_path(@info_request_batch) end @@ -380,12 +374,7 @@ class RequestController < ApplicationController ) end - flash[:notice] = _("<p>Your {{law_used_full}} request has been <strong>sent on its way</strong>!</p> - <p><strong>We will email you</strong> when there is a response, or after {{late_number_of_days}} working days if the authority still hasn't - replied by then.</p> - <p>If you write about this request (for example in a forum or a blog) please link to this page, and add an - annotation below telling people about your writing.</p>",:law_used_full=>@info_request.law_used_full, - :late_number_of_days => AlaveteliConfiguration::reply_late_after_days) + flash[:request_sent] = true redirect_to show_new_request_path(:url_title => @info_request.url_title) end @@ -770,13 +759,13 @@ class RequestController < ApplicationController get_attachment_internal(false) return unless @attachment - # Prevent spam to magic request address. Note that the binary - # subsitution method used depends on the content type - @incoming_message.binary_mask_stuff!(@attachment.body, @attachment.content_type) # we don't use @attachment.content_type here, as we want same mime type when cached in cache_attachments above response.content_type = AlaveteliFileTypes.filename_to_mimetype(params[:file_name]) || 'application/octet-stream' + # Prevent spam to magic request address. Note that the binary + # subsitution method used depends on the content type + @incoming_message.apply_masks!(@attachment.body, @attachment.content_type) if response.content_type == 'text/html' @attachment.body = ActionController::Base.helpers.sanitize(@attachment.body) end @@ -808,10 +797,9 @@ class RequestController < ApplicationController :body_prefix => render_to_string(:partial => "request/view_html_prefix") } ) - - @incoming_message.html_mask_stuff!(html) - response.content_type = 'text/html' + @incoming_message.apply_masks!(html, response.content_type) + render :text => html end @@ -845,7 +833,15 @@ class RequestController < ApplicationController end # check filename in URL matches that in database (use a censor rule if you want to change a filename) - raise ActiveRecord::RecordNotFound.new("please use same filename as original file has, display: '" + @attachment.display_filename + "' old_display: '" + @attachment.old_display_filename + "' original: '" + @original_filename + "'") if @attachment.display_filename != @original_filename && @attachment.old_display_filename != @original_filename + if @attachment.display_filename != @original_filename && @attachment.old_display_filename != @original_filename + msg = 'please use same filename as original file has, display: ' + msg += "'#{ @attachment.display_filename }' " + msg += 'old_display: ' + msg += "'#{ @attachment.old_display_filename }' " + msg += 'original: ' + msg += "'#{ @original_filename }'" + raise ActiveRecord::RecordNotFound.new(msg) + end @attachment_url = get_attachment_url(:id => @incoming_message.info_request_id, :incoming_message_id => @incoming_message.id, :part => @part_number, @@ -904,10 +900,18 @@ class RequestController < ApplicationController # Type ahead search def search_typeahead - # Since acts_as_xapian doesn't support the Partial match flag, we work around it - # by making the last work a wildcard, which is quite the same - query = params[:q] - @xapian_requests = perform_search_typeahead(query, InfoRequestEvent) + # Since acts_as_xapian doesn't support the Partial match flag, we work + # around it by making the last word a wildcard, which is quite the same + @query = '' + + if params.key?(:requested_from) + @query << "requested_from:#{ params[:requested_from] } " + end + + @per_page = (params.fetch(:per_page) { 25 }).to_i + + @query << params[:q] + @xapian_requests = perform_search_typeahead(@query, InfoRequestEvent, @per_page) render :partial => "request/search_ahead" end diff --git a/app/controllers/services_controller.rb b/app/controllers/services_controller.rb index dc4f783a6..9b3a3396f 100644 --- a/app/controllers/services_controller.rb +++ b/app/controllers/services_controller.rb @@ -5,6 +5,8 @@ require 'open-uri' class ServicesController < ApplicationController def other_country_message + flash.keep + text = "" iso_country_code = AlaveteliConfiguration::iso_country_code.downcase if country_from_ip.downcase != iso_country_code diff --git a/app/controllers/track_controller.rb b/app/controllers/track_controller.rb index 144f4d55a..4b272797f 100644 --- a/app/controllers/track_controller.rb +++ b/app/controllers/track_controller.rb @@ -6,9 +6,6 @@ # Email: hello@mysociety.org; WWW: http://www.mysociety.org/ class TrackController < ApplicationController - - protect_from_forgery # See ActionController::RequestForgeryProtection for details - before_filter :medium_cache # Track all updates to a particular request diff --git a/app/controllers/user_controller.rb b/app/controllers/user_controller.rb index 43eb99c58..56f42891d 100644 --- a/app/controllers/user_controller.rb +++ b/app/controllers/user_controller.rb @@ -7,15 +7,8 @@ require 'set' class UserController < ApplicationController - layout :select_layout - protect_from_forgery :only => [ :contact, - :set_profile_photo, - :signchangeemail, - :clear_profile_photo, - :set_profile_about_me ] # See ActionController::RequestForgeryProtection for details - # Show page about a user def show long_cache @@ -260,16 +253,8 @@ class UserController < ApplicationController do_post_redirect post_redirect end - # Logout form - def _do_signout - session[:user_id] = nil - session[:user_circumstance] = nil - session[:remember_me] = false - session[:using_admin] = nil - session[:admin_name] = nil - end def signout - self._do_signout + clear_session_credentials if params[:r] redirect_to URI.parse(params[:r]).path else |