# Copyright (c) 2020 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details. # frozen_string_literal: true cs__scoped_require 'contrast/agent/logger' cs__scoped_require 'contrast/components/interface' cs__scoped_require 'contrast/utils/assess/sampling_util' module Contrast module Utils # Utility class for processing responses from the Contrast Service. Specifically, this class # processes Server and Application settings and updates the Settings component. module ServiceResponseUtil include Contrast::Components::Interface access_component :analysis, :contrast_service, :logging, :settings class << self # TODO: RUBY-119 def process_response response fs = Contrast::Agent::FeatureState.instance fs.last_update = response&.sent_ms server_features = process_server_response(response) app_settings = process_application_response(response) # ReactionProcessor is a design pattern from TeamServer. # Right now, there's one potential reaction, which is disabling the agent Contrast::Agent::ReactionProcessor.process(response&.application_settings) # Determine new accumulator state if (new_accum = response&.accumulator_settings) SETTINGS.accumulator_settings.replace(new_accum) end Contrast::Agent::Logger.instance.update(server_features&.log_file, server_features&.log_level) update_features(server_features, app_settings) logger.trace( 'Agent settings updated in response to Service', protect_on: fs.protect_enabled?, assess_on: fs.assess_enabled?) end private # Given some protobuf messages, update settings. # This is the bridge between Contrast Service <-> Settings. def process_server_response response server_features = response&.server_features return unless server_features logger.trace('Agent: Received updated server features') SETTINGS.update_from_server_features(server_features) server_features end def process_application_response response app_settings = response&.application_settings return unless app_settings logger.debug('Agent: Received updated application settings') SETTINGS.update_from_application_settings(app_settings) app_settings end # This can't go in the Settings component because protect and assess depend on settings # I don't think it should go into contrast_service because that only handles connection specific data def update_features server_features, app_settings return unless !!(server_features || app_settings) logger.trace_with_time('Rebuilding rule modes') do SETTINGS.build_protect_rules if PROTECT.enabled? SETTINGS.build_assess_rules if ASSESS.enabled? logger.info('Current rule settings:') PROTECT.rules.each { |k, v| logger.info('Protect Rule mode set', rule: k, mode: v.mode) } ASSESS.rules.each { |k, v| logger.info('Assess Rule mode set', rule: k, mode: v.enabled?) } end end end end end end