# Copyright (c) 2022 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
# frozen_string_literal: true

require 'contrast/utils/object_share'
require 'contrast/agent/protect/input_analyzer/input_analyzer'
require 'contrast/agent/reporting/attack_result/attack_result'
require 'contrast/agent/reporting/attack_result/rasp_rule_sample'
require 'contrast/utils/input_classification'

module Contrast
  module Agent
    module Protect
      module Rule
        # This module will do the Input Classification stage of HttpMethodTampering rule
        # as a result input would be marked as DEFINETEATTACK or IGNORE,
        # to be analyzed at the sink level.
        module HttpMethodTamperingInputClassification
          # class << self
          #   include InputClassificationBase
          #
          #   # This method will determine actually if the user input is DEFINITEATTACK or IGNORE
          #   #
          #   # @param input_type [Contrast::Agent::Reporting::InputType] the type of the user input
          #   # @param input_analysis [Contrast::Agent::Reporting::InputAnalysis] Holds all the results from the input
          #   # analysis from the current request.
          #   def classify input_type, input_analysis
          #     return unless input_analysis.request
          #     return unless input_type == METHOD
          #
          #     rule_id = Contrast::Agent::Protect::Rule::HttpMethodTampering::NAME
          #
          #     ia_result = method_tampering_new_input_analysis(input_analysis.request, rule_id, input_type)
          #     input_analysis.results << ia_result
          #
          #     return input_analysis if ia_result.score_level == IGNORE
          #
          #     attack_result = build_attack_result ia_result, rule_id
          #
          #     if Contrast::Api::Settings::ProtectionRule::Mode::BLOCK != Contrast::PROTECT.rule_mode(rule_id)
          #       attack_result.response = :EXPLOITED
          #       Contrast::Agent::EXPLOITS.push attack_result
          #       return input_analysis
          #     end
          #
          #     attack_result.response = :BLOCKED
          #     context.activity.results << attack_result
          #     raise Contrast::SecurityException.new(self,
          #                                           'HTTP Method Tampering rule triggered. '\
          #                                           "Call to #{ input_analysis.request.path } with " \
          #                                           "#{ input_analysis.request.request_method } blocked.")
          #   end
          #
          #   private
          #
          #   # @param request [Contrast::Agent::Request] the current request context.
          #   def method_tampering_exploited? request
          #     !Contrast::Agent::Protect::Rule::HttpMethodTampering::APPLICABLE_METHODS_INPUTS.include?(request.request_method) # rubocop:disable Layout/LineLength
          #   end
          #
          #   # This methods checks if input is tagged DEFINITEATTACK or IGNORE matches value with it's
          #   # key if needed and Creates new instance of InputAnalysisResult.
          #   #
          #   # @param request [Contrast::Agent::Request] the current request context.
          #   # @param rule_id [String] The name of the Protect Rule.
          #   # @param input_type [Contrast::Agent::Reporting::InputType] The type of the user input.
          #   #
          #   # @return res [Contrast::Agent::Reporting::InputAnalysisResult]
          #   def method_tampering_new_input_analysis request, rule_id, input_type
          #     ia_result = new_ia_result rule_id, input_type, request.path
          #     if method_tampering_exploited? request
          #       ia_result.score_level = DEFINITEATTACK
          #       ia_result.ids << rule_id
          #     else
          #       ia_result.score_level = IGNORE
          #     end
          #
          #     ia_result
          #   end
          #
          #   def build_attack_result ia_result, rule_id
          #     rasp_rule_sample = Contrast::Agent::Reporting::RaspRuleSample.new.build context, ia_result
          #     result = Contrast::Agent::Reporting::AttackResult.new
          #     result.rule_id = rule_id
          #     result.samples << rasp_rule_sample
          #     result
          #   end
          #
          #   def context
          #     Contrast::Agent::REQUEST_TRACKER.current
          #   end
          # end
        end
      end
    end
  end
end