From 2d3064509b29ed48dbba26c6307af064a8329e1b Mon Sep 17 00:00:00 2001
From: Huzaifa Iftikhar <hiftikhar@gitlab.com>
Date: Tue, 15 Feb 2022 15:43:51 +0000
Subject: [PATCH] Fix Date::Error exception when viewing audit logs for an
 invalid date

Added an early return to the validate_date_params method to fix
the exception raised when an invalid date is passed for either
created_before or created_after parameter. Also, included the
before_action validate_date_params to AuditLogReportsController to
prevent exceptions.

Changelog: fixed
EE: true
---
 .../admin/audit_log_reports_controller.rb     |  1 +
 .../enforces_valid_date_params.rb             | 16 +++++++++--
 .../audit_log_reports_controller_spec.rb      | 28 +++++++++++++++++++
 .../admin/audit_logs_controller_spec.rb       | 21 ++++++++++++++
 .../groups/audit_events_controller_spec.rb    | 21 ++++++++++++++
 .../projects/audit_events_controller_spec.rb  | 21 ++++++++++++++
 6 files changed, 106 insertions(+), 2 deletions(-)

diff --git a/ee/app/controllers/admin/audit_log_reports_controller.rb b/ee/app/controllers/admin/audit_log_reports_controller.rb
index ff17532fee102..3bce589f96f77 100644
--- a/ee/app/controllers/admin/audit_log_reports_controller.rb
+++ b/ee/app/controllers/admin/audit_log_reports_controller.rb
@@ -1,6 +1,7 @@
 # frozen_string_literal: true
 
 class Admin::AuditLogReportsController < Admin::ApplicationController
+  include AuditEvents::EnforcesValidDateParams
   include AuditEvents::DateRange
 
   before_action :validate_audit_log_reports_available!
diff --git a/ee/app/controllers/concerns/audit_events/enforces_valid_date_params.rb b/ee/app/controllers/concerns/audit_events/enforces_valid_date_params.rb
index abd1838eb40f9..7420ac50f093a 100644
--- a/ee/app/controllers/concerns/audit_events/enforces_valid_date_params.rb
+++ b/ee/app/controllers/concerns/audit_events/enforces_valid_date_params.rb
@@ -12,12 +12,24 @@ module EnforcesValidDateParams
 
     def validate_date_params
       unless valid_utc_date?(params[:created_before]) && valid_utc_date?(params[:created_after])
-        flash[:alert] = _('Invalid date format. Please use UTC format as YYYY-MM-DD')
+        respond_to do |format|
+          format.html do
+            flash[:alert] = _('Invalid date format. Please use UTC format as YYYY-MM-DD')
+            render status: :bad_request
+          end
+          format.any { head :bad_request }
+        end
       end
     end
 
     def valid_utc_date?(date)
-      date.blank? || date =~ Gitlab::Regex.utc_date_regex
+      return true if date.blank?
+
+      return false unless date =~ Gitlab::Regex.utc_date_regex
+
+      return true if Date.parse(date)
+    rescue Date::Error
+      false
     end
   end
 end
diff --git a/ee/spec/controllers/admin/audit_log_reports_controller_spec.rb b/ee/spec/controllers/admin/audit_log_reports_controller_spec.rb
index ae996570e539a..594743ee689b7 100644
--- a/ee/spec/controllers/admin/audit_log_reports_controller_spec.rb
+++ b/ee/spec/controllers/admin/audit_log_reports_controller_spec.rb
@@ -3,6 +3,8 @@
 require 'spec_helper'
 
 RSpec.describe Admin::AuditLogReportsController do
+  using RSpec::Parameterized::TableSyntax
+
   describe 'GET index' do
     let(:csv_data) do
       <<~CSV
@@ -105,6 +107,32 @@
             end
           end
         end
+
+        context 'when invalid date params are provided' do
+          let(:params) do
+            {
+              created_before: created_before,
+              created_after: created_after
+            }
+          end
+
+          where(:created_before, :created_after) do
+            'invalid-date' | nil
+            nil            | true
+            '2021-13-10'   | nil
+            nil            | '2021-02-31'
+            '2021-03-31'   | '2021-02-31'
+          end
+
+          with_them do
+            it 'returns an error' do
+              subject
+
+              expect(response).to have_gitlab_http_status(:bad_request)
+              expect(flash[:alert]).to eq nil
+            end
+          end
+        end
       end
 
       context 'when unlicensed' do
diff --git a/ee/spec/controllers/admin/audit_logs_controller_spec.rb b/ee/spec/controllers/admin/audit_logs_controller_spec.rb
index e7b9e097b6cd4..4feecb1d39a8b 100644
--- a/ee/spec/controllers/admin/audit_logs_controller_spec.rb
+++ b/ee/spec/controllers/admin/audit_logs_controller_spec.rb
@@ -3,6 +3,8 @@
 require 'spec_helper'
 
 RSpec.describe Admin::AuditLogsController do
+  using RSpec::Parameterized::TableSyntax
+
   let_it_be(:admin) { create(:admin) }
 
   describe 'GET #index' do
@@ -42,6 +44,25 @@
           user: admin
         )
       end
+
+      context 'when invalid date' do
+        where(:created_before, :created_after) do
+          'invalid-date' | nil
+          nil            | true
+          '2021-13-10'   | nil
+          nil            | '2021-02-31'
+          '2021-03-31'   | '2021-02-31'
+        end
+
+        with_them do
+          it 'returns an error' do
+            get :index, params: { 'created_before': created_before, 'created_after': created_after }
+
+            expect(response).to have_gitlab_http_status(:bad_request)
+            expect(flash[:alert]).to eq 'Invalid date format. Please use UTC format as YYYY-MM-DD'
+          end
+        end
+      end
     end
 
     context 'by user' do
diff --git a/ee/spec/controllers/groups/audit_events_controller_spec.rb b/ee/spec/controllers/groups/audit_events_controller_spec.rb
index 474941bd36375..be77114294346 100644
--- a/ee/spec/controllers/groups/audit_events_controller_spec.rb
+++ b/ee/spec/controllers/groups/audit_events_controller_spec.rb
@@ -3,6 +3,8 @@
 require 'spec_helper'
 
 RSpec.describe Groups::AuditEventsController do
+  using RSpec::Parameterized::TableSyntax
+
   let_it_be(:user) { create(:user) }
   let_it_be(:owner) { create(:user) }
   let_it_be(:group) { create(:group, :private) }
@@ -139,6 +141,25 @@
               namespace: group
             )
           end
+
+          context 'when invalid date' do
+            where(:created_before, :created_after) do
+              'invalid-date' | nil
+              nil            | true
+              '2021-13-10'   | nil
+              nil            | '2021-02-31'
+              '2021-03-31'   | '2021-02-31'
+            end
+
+            with_them do
+              it 'returns an error' do
+                get :index, params: { group_id: group.to_param, 'created_before': created_before, 'created_after': created_after }
+
+                expect(response).to have_gitlab_http_status(:bad_request)
+                expect(flash[:alert]).to eq 'Invalid date format. Please use UTC format as YYYY-MM-DD'
+              end
+            end
+          end
         end
       end
 
diff --git a/ee/spec/controllers/projects/audit_events_controller_spec.rb b/ee/spec/controllers/projects/audit_events_controller_spec.rb
index 9a6fc319035ff..f05c223093cf0 100644
--- a/ee/spec/controllers/projects/audit_events_controller_spec.rb
+++ b/ee/spec/controllers/projects/audit_events_controller_spec.rb
@@ -3,6 +3,8 @@
 require 'spec_helper'
 
 RSpec.describe Projects::AuditEventsController do
+  using RSpec::Parameterized::TableSyntax
+
   let_it_be(:user) { create(:user) }
   let_it_be(:maintainer) { create(:user) }
   let_it_be(:project) { create(:project, :private) }
@@ -110,6 +112,25 @@
             it_behaves_like 'orders by id descending'
           end
         end
+
+        context 'when invalid date' do
+          where(:created_before, :created_after) do
+            'invalid-date' | nil
+            nil            | true
+            '2021-13-10'   | nil
+            nil            | '2021-02-31'
+            '2021-03-31'   | '2021-02-31'
+          end
+
+          with_them do
+            it 'returns an error' do
+              get :index, params: { project_id: project.to_param, namespace_id: project.namespace.to_param, 'created_before': created_before, 'created_after': created_after }
+
+              expect(response).to have_gitlab_http_status(:bad_request)
+              expect(flash[:alert]).to eq 'Invalid date format. Please use UTC format as YYYY-MM-DD'
+            end
+          end
+        end
       end
 
       context 'pagination' do
-- 
GitLab