# Copyright (c) 2022 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details. # frozen_string_literal: true require 'contrast/agent/reporting/reporting_events/route_discovery_observation' require 'contrast/api/dtm.pb' module Contrast module Agent module Reporting # This is the new Route Discovery class which will include all the needed information for the new reporting # system to relay this information in the Application Update messages. These discoveries 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. They may or # may not have been invoked at the time of reporting. # # @attr_reader observations [observations] the routes and verbs seen that match to this Route # @attr_reader signature [String] the unique identifier for this route; typically the method signature. Required # for reporting. class RouteDiscovery # required attributes attr_reader :observations, :signature class << self # Convert a DTM for SpeedRacer to an Event for TeamServer. # # @param route_coverage_dtm [Contrast::Api::Dtm::RouteCoverage] # @return [Contrast::Agent::Reporting::RouteDiscovery] def convert route_coverage_dtm report = new report.attach_data(route_coverage_dtm) report end end # Attach the data from the protobuf models to this reporter so that it can be sent to TeamServer directly # # @param route_coverage_dtm [Contrast::Api::Dtm::RouteCoverage] def attach_data route_coverage_dtm @signature = route_coverage_dtm.route @observations = [] observations << Contrast::Agent::Reporting::RouteDiscoveryObservation.convert(route_coverage_dtm) 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 { count: 0, # we have this to make TS happy observations: @observations.map(&:to_controlled_hash), signature: @signature } end # Ensure the required fields are present. # # @raise [ArgumentError] def validate raise(ArgumentError, "#{ self } did not have a proper signature. Unable to continue.") unless signature end end end end end