# Copyright (c) 2023 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details. # frozen_string_literal: true require 'contrast/agent/patching/policy/method_policy_extend' module Contrast module Agent module Patching module Policy # This class is used to map each method to the trigger node that applies to it class MethodPolicy extend Contrast::Agent::Patching::Policy::MethodPolicyExtend attr_reader :deadzone_node, :inventory_node, :propagation_node, :protect_node, :trigger_node attr_accessor :source_node, :method_name, :method_visibility, :instance_method # Initialize new method policy with: # # @param method_policy [Hash] # { # source_node [ Contrast::Agent::Assess::Policy::SourceNode ] # propagation_node [ Contrast::Agent::Assess::Policy::PropagationNode ] # trigger_node [ Contrast::Agent::Assess::Policy::TriggerNode ] # inventory_node [ Contrast::Agent::Inventory::Policy::TriggerNode ] # protect_node [ Contrast::Agent::Protect::Policy::TriggerNode ] # deadzone_node [ Contrast::Agent::Deadzone::Policy::DeadzoneNode ] # method_name [ Symbol ] # the name of the method for this policy # method_visibility [ Symbol ] # Public, Private Protected # instance_method [ Boolean ] # true if this method is an instance method # } def initialize method_policy @method_name = method_policy[:method_name] @method_visibility = method_policy[:method_visibility] @instance_method = method_policy[:instance_method] @source_node = method_policy[:source_node] @propagation_node = method_policy[:propagation_node] @trigger_node = method_policy[:trigger_node] @inventory_node = method_policy[:inventory_node] @protect_node = method_policy[:protect_node] @deadzone_node = method_policy[:deadzone_node] end def private_method? method_visibility == :private end def empty? nodes.none? end def scopes_to_enter @_scopes_to_enter ||= method_scopes end def scopes_to_exit @_scopes_to_exit ||= method_scopes.reverse end def requires_custom_patch? !!@trigger_node&.custom_patch? end private def nodes @_nodes ||= [ source_node, propagation_node, trigger_node, inventory_node, protect_node, deadzone_node ].compact end def method_scopes # Implicitly, the scope precedence is the node order # defined by #nodes. @_method_scopes ||= nodes.flat_map(&:method_scope).tap(&:compact!).tap(&:uniq!) end end end end end end