module Sqreen::Rules

Rules related method/functions

Sqreen rules

Public Class Methods

cb_from_rule(hash_rule, instrumentation_engine=nil, metrics_store = nil, verifier = nil) click to toggle source

Given a rule, will instantiate the related callback. @param hash_rule [Hash] Rules metadata @param instrumentation_engine [Instrumentation] Instrumentation engine @param metrics_store [MetricStore] Metrics storage facility @param verifier [SqreenSignedVerifier] Signed verifier

# File lib/sqreen/rules.rb, line 79
def self::cb_from_rule(hash_rule, instrumentation_engine=nil, metrics_store = nil, verifier = nil)
  # Check rules signature
  if verifier
    raise InvalidSignatureException unless verifier.verify(hash_rule)
  end

  hook = hash_rule[Attrs::HOOKPOINT]
  klass = hook[Attrs::KLASS]

  # The instrumented class can be from anywhere
  instr_class = Rules.walk_const_get klass

  if instr_class.nil?
    rule_name = hash_rule[Attrs::NAME]
    Sqreen.log.debug { "#{klass} does not exists. Skipping #{rule_name}" }
    return nil
  end

  instr_method = hook[Attrs::METHOD]
  instr_method = instr_method.to_sym
  if instrumentation_engine &&
     !instrumentation_engine.valid_method?(instr_class, instr_method)

    Sqreen.log.debug { "#{instr_method} does not exist on #{klass} Skipping #{rule_name}" }
    return nil
  end

  cbname = hook[Attrs::CALLBACK_CLASS]

  cb_class = nil
  js = hash_rule[Attrs::CALLBACKS]

  if js && !Sqreen::Js::JsService.instance.online?
    unless @issue_nojs_warn
      @issue_nojs_warn = true
      Sqreen.log.warn('No JavaScript engine is available. ' \
          'JavaScript callbacks will be ignored')
    end
    Sqreen.log.debug("Ignoring JS callback #{rule_name}")
    return nil
  end

  cb_class = ExecJSCB if js

  if cbname
    cb_class = if cbname.include?('::')
                 # Only load callbacks from sqreen
                 Rules.walk_const_get(cbname) if cbname.start_with?('::Sqreen::', 'Sqreen::')
               else
                 Rules.const_get(cbname) if Rules.const_defined?(cbname) # rubocop:disable Style/IfInsideElse
               end
  end

  if cb_class.nil?
    Sqreen.log.debug { "Cannot setup #{cbname.inspect} [#{rule_name}]" }
    return nil
  end

  unless cb_class.ancestors.include?(RuleCB)
    Sqreen.log.debug "#{cb_class} does not inherit from RuleCB"
    return nil
  end

  rule_cb = cb_class.new(instr_class, instr_method, hash_rule)

  if metrics_store
    (hash_rule[Attrs::METRICS] || []).each do |metric|
      metrics_store.create_metric(metric, rule_cb)
    end
  end

  rule_cb
rescue => e
  rule_name = nil
  rulespack_id = nil
  if hash_rule.respond_to?(:[])
    rule_name = hash_rule[Attrs::NAME]
    rulespack_id = hash_rule[Attrs::RULESPACK_ID]
  end
  Sqreen::RemoteException.record(
    'exception' => e,
    'rulespack_id' => rulespack_id,
    'rule_name' => rule_name)
  Sqreen.log.debug { "Creating cb from rule #{rule_name} failed (#{e.inspect})" }
  nil
end
local(configuration) click to toggle source
# File lib/sqreen/rules.rb, line 61
def self::local(configuration)
  # Parse and return local rules (path defined in environment)

  path = configuration.get(:local_rules)
  return [] unless path
  begin
    File.open(path) { |f| JSON.load(f) }
  rescue Errno::ENOENT
    Sqreen.log.error "File '#{path}' not found"
    []
  end
end
walk_const_get(str) click to toggle source
# File lib/sqreen/rules.rb, line 166
def self::walk_const_get(str)
  obj = Object
  str.split('::').compact.each do |part|
    return nil unless obj.const_defined?(part)
    obj = obj.const_get(part)
  end
  obj
end