# Copyright (c) 2022 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details. # frozen_string_literal: true require 'json' require 'contrast/components/logger' require 'contrast/agent/reporting/reporting_events/application_reporting_event' require 'contrast/utils/object_share' module Contrast module Agent module Reporting # This is the new Route Observation class which will include all the needed information for the new reporting # system to relay this information in the Route Observation messages. These observations are used by TeamServer # to construct the route coverage information for the assess feature. They represent those methods which map to # externally accessible endpoints within the application, as registered to the application framework. This also # includes the literal URL and HTTP Verb used to invoke them, as they must have been called at this point to be # recorded. class ObservedRoute < Contrast::Agent::Reporting::ApplicationReportingEvent # @param [String] the method signature used to uniquely identify the coverage report. attr_accessor :signature # @param [String] the normalized URL used to access the method in the route. attr_accessor :url # @param [String] the HTTP Verb used to access the method in the route. attr_accessor :verb # @param [Array<Contrast::Agent::Reporting::TraceEventSource>] the sources of user input accessed during this # request. Used for remediation determinations in TeamServer. attr_reader :sources def initialize @event_endpoint = Contrast::Agent::Reporting::Endpoints.observed_route @sources = [] @signature = Contrast::Utils::ObjectShare::EMPTY_STRING @verb = Contrast::Utils::ObjectShare::EMPTY_STRING @url = Contrast::Utils::ObjectShare::EMPTY_STRING super() end def file_name 'routes-observed' end # Convert the instance variables on the class, and other information, into the identifiers required for # TeamServer to process the JSON form of this message. # # @return [Hash] # @raise [ArgumentError] def to_controlled_hash validate rc_hash = { session_id: @agent_session_id_value, sources: @sources.map(&:to_controlled_hash), signature: @signature, verb: @verb, url: @url } rc_hash.delete(:verb) unless @verb rc_hash end def validate raise(ArgumentError, "#{ self } did not have a proper sources. Unable to continue.") if @sources.nil? raise(ArgumentError, "#{ self } did not have a proper signature. Unable to continue.") unless signature raise(ArgumentError, "#{ self } did not have a proper url. Unable to continue.") unless url nil end end end end end