Module: Metasploit::Model::Search::With

Extended by:
ActiveSupport::Concern
Included in:
Metasploit::Model::Search, Attribute
Defined in:
lib/metasploit/model/search/with.rb

Overview

Generalizes operators from attributes to anything directly registered as an operator on a class.

Declaring operator classes

Interface

Operators do not need to subclass any specific superclass, but they are expected to define certain methods.

class MyOperator
  #
  # Instance Methods
  #

  # @param klass [Class] The klass on which `search_with` was called.
  def initialize(attributes={})
    # ...
  end

  # Description of what this operator searches for.
  #
  # @return [String]
  def help
    # ...
  end

  # Name of this operator.  The name of the operator is matched to the string before the ':' in a formatted
  # operation.
  #
  # @return [Symbol]
  def name
    # ...
  end

  # Creates a one or more operations based on `formatted_value`.
  #
  # @return [#operator, Array<#operator>] Operation with this operator as the operation's `operator`.
  def operate_on(formatted_value)
    # ...
  end
end

Help

Instead of having define your own #help method for your operator Class, you can include Operator::Help.

This allows the help to be looked up using I18n, and for the help to be customized based on the following criteria:

klass on which the operator is declared, including any Module#ancestors and the operator name

# config/locales/<lang>.yml
<lang>:
  <klass.i18n_scope>:
    ancestors:
      <klass_ancestor.model_name.i18n_key>:
        search:
          operator:
            names:
              <name>:
                help: "Help for searching <name> on <klass>"

class of the operator, including any Module#ancestors and the operator name

# config/locales/<lang>.yml
<lang>:
  <operator.class.i18n_scope>:
    search:
      operator:
        ancestors:
          <operator_class_ancestor.model_name.i18n_key>:
            <name>:
              help: "Help for searching <name> using <operator.class>"

class of the operator, including any Module#ancestors without the operator name

# config/locales/<lang>.yml
<lang>:
  <operator.class.i18n_scope>:
    search:
      operator:
        ancestors:
          <operator_class_ancestor.model_name.i18n_key>:
            help: "Help for searching using <operator.class>"

Operator::Base

Instead of writing an operator completely from scratch, you can subclass Operator::Base.

class MyOperator < Metasploit::Model::Search::Operator::Base
  # Name of this operator.  The name of the operator is matched to the string before the ':' in a formatted
  # operation.
  #
  # @return [Symbol]
  def name
    # ...
  end

  # Creates a one or more operations based on `formatted_value`.
  #
  # @return [#operator, Array<#operator>] Operation with this operator as the operation's `operator`.
  def operate_on(formatted_value)
    # ...
  end
end

Operator::Single

If all you want do is customize the name and operation Class that your custom operator class returns from #operate_on, then you can subclass Operator::Single instead of Operator::Base.

class MyOperator < Metasploit::Model::Search::Operator::Single
  # Name of this operator.  The name of the operator is matched to the string before the ':' in a formatted
  # operation.
  #
  # @return [Symbol]
  def name
    # ...
  end

  # `Class.name` of `Class` returned from {Metasploit::Model::Search::Operator::Single#operate_on}.
  #
  # @return [String] a `Class.name`
  def operation_class_name
    # ...
  end
end

Testing

ClassMethods#search_with calls can be tested with the 'search_with' shared example. First, ensure the shared examples from metasploit-model are required in your spec_helper.rb:

# spec/spec_helper.rb
support_glob = Metasploit::Model::Engine.root.join('spec', 'support', '**', '*.rb')

Dir.glob(support_glob) do |path|
  require path
end

In the spec fo the Class that called search_with, use the 'search_with' shared example by passing the arguments passed to ClassMethods#search_attribute.

# app/models/my_class.rb
class MyClass
  include Metasploit::Model::Search

  #
  # Search
  #

  search_with MyOperatorClass,
              foo: :bar
end

# spec/app/models/my_class_spec.rb
require 'spec_helper'

describe MyClass do
  context 'search' do
    context 'attributes' do
      it_should_behave_like 'search_with',
                            MyOperatorClass,
                            foo: :bar
    end
  end
end

Defined Under Namespace

Modules: ClassMethods