diff --git a/.rubocop.yml b/.rubocop.yml index 8fe38aee7f..6f596d01b8 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -16,6 +16,9 @@ AllCops: - app/api/search_consumer/**/* - app/controllers/sites/templated_font_and_colors_controller.rb - app/controllers/sites/templates_controller.rb + # The Agencies API is deprecated and will be removed - SRCH-1574 + - app/controllers/api/v1/agencies_controller.rb + - app/controllers/api/v2/agencies_controller.rb Metrics/BlockLength: Exclude: diff --git a/app/controllers/api/v1/agencies_controller.rb b/app/controllers/api/v1/agencies_controller.rb index 7c80737f21..eeb535e06c 100644 --- a/app/controllers/api/v1/agencies_controller.rb +++ b/app/controllers/api/v1/agencies_controller.rb @@ -1,3 +1,4 @@ +# deprecated: SRCH-1574 module Api module V1 class AgenciesController < ApplicationController diff --git a/app/controllers/api/v1/search_controller.rb b/app/controllers/api/v1/search_controller.rb new file mode 100644 index 0000000000..82da0faee5 --- /dev/null +++ b/app/controllers/api/v1/search_controller.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +module Api + module V1 + class SearchController < ApplicationController + DEPRECATION_MESSAGE = 'This API endpoint has been deprecated. Please refer to https://search.gov/developer/ for information on current Search.gov APIs.' + + def search + render plain: DEPRECATION_MESSAGE, status: :not_found + end + end + end +end diff --git a/app/controllers/api/v2/agencies_controller.rb b/app/controllers/api/v2/agencies_controller.rb index 871ccc29ea..3ac43c4b85 100644 --- a/app/controllers/api/v2/agencies_controller.rb +++ b/app/controllers/api/v2/agencies_controller.rb @@ -1,3 +1,4 @@ +# deprecated: SRCH-1574 module Api module V2 class AgenciesController < ApplicationController diff --git a/app/controllers/api_controller.rb b/app/controllers/api_controller.rb deleted file mode 100644 index ce6143efb6..0000000000 --- a/app/controllers/api_controller.rb +++ /dev/null @@ -1,43 +0,0 @@ -class ApiController < ApplicationController - DEFAULT_API_PER_PAGE = 10.freeze - before_action :load_affiliate - - def search - @search_options = search_options_from_params.merge( - format: params[:format], index: params[:index], per_page: DEFAULT_API_PER_PAGE, lat_lon: params[:lat_lon]) - @search = ApiSearch.new(@search_options) - results = @search.run - SearchImpression.log(@search, get_vertical(params[:index]), params, request) - respond_to do |format| - format.xml { render :xml => results } - format.json { render(:json => results) } - end - rescue ActionController::UnknownFormat - head :not_acceptable - end - - private - - def load_affiliate - @affiliate = Affiliate.active.find_by_name(params[:affiliate].to_s) if params[:affiliate].present? - unless @affiliate and WhitelistedV1ApiHandle.exists?(handle: @affiliate.name) - render plain: 'Not Found', status: 404 - false - end - end - - def get_vertical(index) - case index - when "news" - :news - when "videonews" - :news - when "images" - :image - when "docs" - :docs - else - :web - end - end -end diff --git a/config/routes.rb b/config/routes.rb index 53c6946c80..14ac4e31c1 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -3,7 +3,6 @@ concern :active_scaffold_association, ActiveScaffold::Routing::Association.new concern :active_scaffold, ActiveScaffold::Routing::Basic.new(association: true) get '/search' => 'searches#index', as: :search - get '/api/search' => 'api#search', as: :api_search get '/search/advanced' => 'searches#advanced', as: :advanced_search get '/search/images' => 'image_searches#index', as: :image_search get '/search/docs' => 'searches#docs', as: :docs_search @@ -11,6 +10,9 @@ get '/search/news/videos' => 'searches#video_news', as: :video_news_search get '/auth/logindotgov/callback', to: 'omniauth_callbacks#login_dot_gov' + # Deprecated + get '/api/search' => 'api/v1/search#search', as: :api_search + namespace :api, defaults: { format: :json } do namespace :v1 do get '/agencies/search' => 'agencies#search' diff --git a/lib/middlewares/reject_invalid_request_uri.rb b/lib/middlewares/reject_invalid_request_uri.rb index 2380b8f2fb..4627b49ff6 100644 --- a/lib/middlewares/reject_invalid_request_uri.rb +++ b/lib/middlewares/reject_invalid_request_uri.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class RejectInvalidRequestUri def initialize(app) @app = app @@ -6,12 +8,12 @@ def initialize(app) def call(env) if env['REQUEST_URI'] uri = begin - CGI::unescape(env['REQUEST_URI'].force_encoding('UTF-8')) + CGI.unescape(env['REQUEST_URI'].dup.force_encoding('UTF-8')) rescue ArgumentError nil end - return [400, { 'Content-Type' => 'text/html', 'Content-Length' => '0' }, []] if uri.nil? || (uri.is_a?(String) and !uri.valid_encoding?) + return [400, { 'Content-Type' => 'text/html', 'Content-Length' => '0' }, []] if uri.nil? || (uri.is_a?(String) && !uri.valid_encoding?) end @app.call(env) end -end \ No newline at end of file +end diff --git a/spec/controllers/api_controller_spec.rb b/spec/controllers/api_controller_spec.rb deleted file mode 100644 index 7086899f5b..0000000000 --- a/spec/controllers/api_controller_spec.rb +++ /dev/null @@ -1,173 +0,0 @@ -require 'spec_helper' - -describe ApiController do - fixtures :affiliates, :users, :site_domains, :features, :whitelisted_v1_api_handles - - describe '#search' do - let(:affiliate) { affiliates(:basic_affiliate) } - - context 'when the affiliate does not exist' do - let(:affiliate) { mock_model(Affiliate) } - - before do - allow(affiliate).to receive_message_chain(:active, :find_by_name).with('missingaffiliate').and_return(nil) - get :search, params: { affiliate: 'missingaffiliate' } - end - - it { is_expected.to respond_with :not_found } - end - - context 'when the affiliate is not on the v1 whitelist' do - before do - WhitelistedV1ApiHandle.delete_all - get :search, params: { affiliate: 'usagov' } - end - - it { is_expected.to respond_with :not_found } - end - - context 'when the params[:affiliate] is not a string' do - before { get :search, params: { affiliate: { 'foo' => 'bar' } } } - - it { is_expected.to respond_with :not_found } - end - - describe 'with format=json' do - let(:api_search) { double(ApiSearch, query: 'pdf', modules: [], diagnostics: {}) } - - before do - json = { result_field: 'result' }.to_json - expect(ApiSearch).to receive(:new).with(hash_including(affiliate: affiliate, query: 'solar')).and_return(api_search) - allow(api_search).to receive(:run).and_return(json) - get :search, - params: { - affiliate: affiliate.name, - format: 'json', - query: 'solar' - } - end - - it { is_expected.to respond_with :success } - - describe 'response body' do - subject { JSON.parse(response.body) } - its(['result_field']) { should == 'result' } - end - end - - context 'with format=xml' do - let(:api_search) { double(ApiSearch, query: 'pdf', modules: [], diagnostics: {}) } - - before do - xml = { result_field: 'result' }.to_xml - expect(ApiSearch).to receive(:new).with(hash_including(affiliate: affiliate, query: 'solar')).and_return(api_search) - allow(api_search).to receive(:run).and_return(xml) - get :search, - params: { - affiliate: affiliate.name, - format:'xml', - query: 'solar' - } - end - - it { is_expected.to respond_with :success } - - describe 'response body' do - subject { Hash.from_xml(response.body)['hash'] } - - its(['result_field']) { should == 'result' } - end - end - - context 'with format=html' do - before do - get :search, - params: { - affiliate: affiliate.name, - format: :html - } - end - - it { is_expected.to respond_with :not_acceptable } - end - - describe 'options' do - before :each do - @auth_params = { affiliate: affiliates(:basic_affiliate).name } - end - - it 'should set the affiliate' do - get :search, params: @auth_params - expect(assigns[:search_options][:affiliate]).to eq(affiliates(:basic_affiliate)) - end - - it 'should set the query' do - get :search, params: @auth_params.merge(query: 'fish') - expect(assigns[:search_options][:query]).to eq('fish') - end - - it 'should set the lat_lon' do - get :search, params: @auth_params.merge(query: 'fish', lat_lon: '37.7676,-122.5164') - expect(assigns[:search_options][:lat_lon]).to eq('37.7676,-122.5164') - end - end - - describe 'logging searches and impressions' do - let(:api_search) { double(ApiSearch, query: 'pdf', modules: [], run: nil) } - - before do - expect(ApiSearch).to receive(:new).and_return(api_search) - end - - context "when it's web" do - it 'should log the impression with the :web vertical' do - params = {'affiliate' => affiliate.name, 'query' => 'foo', 'index' => 'web'} - expect(SearchImpression).to receive(:log).with(api_search, :web, hash_including(params), instance_of(ActionController::TestRequest)) - get :search, params: params - end - end - - context "when it's image" do - it 'should log the impression with the :image vertical' do - params = {'affiliate' => affiliate.name, 'query' => 'foo', 'index' => 'images'} - expect(SearchImpression).to receive(:log).with(api_search, :image, hash_including(params), instance_of(ActionController::TestRequest)) - get :search, params: params - end - end - - context "when it's news" do - it 'should log the impression with the :news vertical' do - params = {'affiliate' => affiliate.name, 'query' => 'foo', 'index' => 'news'} - expect(SearchImpression).to receive(:log).with(api_search, :news, hash_including(params), instance_of(ActionController::TestRequest)) - get :search, params: params - end - end - - context "when it's videonews" do - it 'should log the impression with the :news vertical' do - params = {'affiliate' => affiliate.name, 'query' => 'foo', 'index' => 'videonews'} - expect(SearchImpression).to receive(:log).with(api_search, :news, hash_including(params), instance_of(ActionController::TestRequest)) - get :search, params: params - end - end - - context "when it's document collections (docs)" do - it 'should log the impression with the :docs vertical' do - params = {'affiliate' => affiliate.name, 'query' => 'foo', 'index' => 'docs'} - expect(SearchImpression).to receive(:log).with(api_search, :docs, hash_including(params), instance_of(ActionController::TestRequest)) - get :search, params: params - end - end - - context "when it's undefined" do - it 'should log the impression with the :web vertical' do - params = {'affiliate' => affiliate.name, 'query' => 'foo'} - expect(SearchImpression).to receive(:log).with(api_search, :web, hash_including(params), instance_of(ActionController::TestRequest)) - get :search, params: params - end - end - end - - end - -end diff --git a/spec/requests/api/v1/search_spec.rb b/spec/requests/api/v1/search_spec.rb new file mode 100644 index 0000000000..995762da1e --- /dev/null +++ b/spec/requests/api/v1/search_spec.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +describe '/api/search' do + let(:endpoint) { '/api/search' } + + before { get endpoint } + + it 'returns a 404' do + expect(response.status).to eq 404 + end + + it 'provides a useful message' do + expect(response.body).to match(/This API endpoint has been deprecated/) + end +end