diff options
Diffstat (limited to 'app/controllers/api_controller.rb')
-rw-r--r-- | app/controllers/api_controller.rb | 142 |
1 files changed, 83 insertions, 59 deletions
diff --git a/app/controllers/api_controller.rb b/app/controllers/api_controller.rb index e6b0c121a..4473139d1 100644 --- a/app/controllers/api_controller.rb +++ b/app/controllers/api_controller.rb @@ -1,5 +1,9 @@ class ApiController < ApplicationController before_filter :check_api_key + before_filter :check_external_request, + :only => [:add_correspondence, :update_state] + before_filter :check_request_ownership, + :only => [:add_correspondence, :update_state] def show_request @request = InfoRequest.find(params[:id]) @@ -9,16 +13,11 @@ class ApiController < ApplicationController :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), - :request_email => @request.incoming_email, - :request_text => @request.last_event_forming_initial_request.outgoing_message.body, } if @request.user @@ -73,35 +72,19 @@ class ApiController < ApplicationController '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 = json["sent_at"] + new_state = params["state"] 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 @@ -116,6 +99,10 @@ class ApiController < ApplicationController errors << "You cannot attach files to messages in the 'request' direction" end + if new_state && !InfoRequest.allowed_incoming_states.include?(new_state) + errors << "'#{new_state}' is not a valid request state" + end + if !errors.empty? render :json => { "errors" => errors }, :status => 500 return @@ -125,16 +112,16 @@ class ApiController < ApplicationController # In the 'request' direction, i.e. what we (Alaveteli) regard as outgoing outgoing_message = OutgoingMessage.new( - :info_request => request, + :info_request => @request, :status => 'ready', :message_type => 'followup', :body => body, :last_sent_at => sent_at, :what_doing => 'normal_sort' ) - request.outgoing_messages << outgoing_message - request.save! - request.log_event("followup_sent", + @request.outgoing_messages << outgoing_message + @request.save! + @request.log_event("followup_sent", :api => true, :email => nil, :outgoing_message_id => outgoing_message.id, @@ -154,12 +141,48 @@ class ApiController < ApplicationController ) end - mail = RequestMailer.external_response(request, body, sent_at, attachment_hashes) + mail = RequestMailer.external_response(@request, body, sent_at, attachment_hashes) + + @request.receive(mail, mail.encoded, true) - request.receive(mail, mail.encoded, true) + if new_state + # we've already checked above that the status is valid + # so no need to check a second time + event = @request.log_event("status_update", + { :script => "#{@public_body.name} via API", + :old_described_state => @request.described_state, + :described_state => new_state, + }) + @request.set_described_state(new_state) + end end render :json => { - 'url' => make_url("request", request.url_title), + 'url' => make_url("request", @request.url_title), + } + end + + def update_state + new_state = params["state"] + + if InfoRequest.allowed_incoming_states.include?(new_state) + ActiveRecord::Base.transaction do + event = @request.log_event("status_update", + { :script => "#{@public_body.name} on behalf of requester via API", + :old_described_state => @request.described_state, + :described_state => new_state, + }) + @request.set_described_state(new_state) + end + else + render :json => { + "errors" => ["'#{new_state}' is not a valid request state" ] + }, + :status => 500 + return + end + + render :json => { + 'url' => make_url("request", @request.url_title), } end @@ -168,40 +191,27 @@ class ApiController < ApplicationController raise PermissionDenied.new("#{@public_body.id} != #{params[:id]}") if @public_body.id != params[:id].to_i since_date_str = params[:since_date] + event_type_clause = "event_type in ('sent', 'followup_sent', 'resent', 'followup_resent')" if since_date_str.nil? - @events = InfoRequestEvent.find_by_sql([ - %(select info_request_events.* - from info_requests - join info_request_events on info_requests.id = info_request_events.info_request_id - where info_requests.public_body_id = ? - and info_request_events.event_type in ( - 'sent', 'followup_sent', 'resent', 'followup_resent' - ) - order by info_request_events.created_at desc - ), @public_body.id - ]) - else + where_params = event_type_clause + else begin - since_date = Date.strptime(since_date_str, "%Y-%m-%d") + since_date = Date.strptime(since_date_str, "%Y-%m-%d") rescue ArgumentError - render :json => {"errors" => [ - "Parameter since_date must be in format yyyy-mm-dd (not '#{since_date_str}')" ] }, - :status => 500 - return + render :json => {"errors" => [ + "Parameter since_date must be in format yyyy-mm-dd (not '#{since_date_str}')" ] }, + :status => 500 + return end - @events = InfoRequestEvent.find_by_sql([ - %(select info_request_events.* - from info_requests - join info_request_events on info_requests.id = info_request_events.info_request_id - where info_requests.public_body_id = ? - and info_request_events.event_type in ( - 'sent', 'followup_sent', 'resent', 'followup_resent' - ) - and info_request_events.created_at >= ? - order by info_request_events.created_at desc - ), @public_body.id, since_date - ]) + event_type_clause << " AND info_request_events.created_at >= ?" + where_params = [event_type_clause, since_date] end + @events = InfoRequestEvent.where(where_params) \ + .joins(:info_request) \ + .where("public_body_id = ?", @public_body.id) \ + .includes([{:info_request => :user}, :outgoing_message]) \ + .order('info_request_events.created_at DESC') + if feed_type == "atom" render :template => "api/request_events", :formats => ['atom'], :layout => false elsif feed_type == "json" @@ -224,7 +234,6 @@ class ApiController < ApplicationController :request_email => request.incoming_email, :title => request.title, :body => event.outgoing_message.body, - :user_name => request.user_name, } if request.user @@ -246,6 +255,21 @@ class ApiController < ApplicationController raise PermissionDenied if @public_body.nil? end + def check_external_request + @request = InfoRequest.find_by_id(params[:id]) + if @request.nil? + render :json => { "errors" => ["Could not find request #{params[:id]}"] }, :status => 404 + elsif !@request.is_external? + render :json => { "errors" => ["Request #{params[:id]} cannot be updated using the API"] }, :status => 403 + end + end + + def check_request_ownership + if @request.public_body_id != @public_body.id + render :json => { "errors" => ["You do not own request #{params[:id]}"] }, :status => 403 + end + end + private def make_url(*args) "http://" + AlaveteliConfiguration::domain + "/" + args.join("/") |