Class: Metasploit::Model::Search::Query

Inherits:
Base
  • Object
show all
Defined in:
app/models/metasploit/model/search/query.rb

Overview

Once search operators are defined, a formatted query, composed of space separated formatted operation, <operator.name>:<formatted_value>, can be parsed to produce a validatable query.

query = Metasploit::Model::Search::Query.new(
  formatted: 'parts.number:1 parts.number:2 parts.uuid:EX,QR'
)

Operations using the same operator are unioned together, while operations with different operator are intersected together, so the above formatted query can be thought of as (parts.number:1 || parts.number:2) && parts.uuid:EX,QR.

Results

Once a Query is defined, it needs to be converted to a data store specific visitor.

Visitors for ActiveRecord are defined in MetasploitDataModels::Search::Visitor.

If you want to define your own visitors, you can subclass Visitation::Visitor.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Base

#initialize, #valid!

Constructor Details

This class inherits a constructor from Metasploit::Model::Base

Instance Attribute Details

#formattedString

Query string containing space separated : pairs.

Returns:

  • (String)


30
31
32
# File 'app/models/metasploit/model/search/query.rb', line 30

def formatted
  @formatted
end

#formatted_operationsArray<String>

#formatted broken up into individual operation (:) Strings.

Returns:

  • (Array<String>)


38
# File 'app/models/metasploit/model/search/query.rb', line 38

attr_writer :formatted_operations

#klassClass, #search_operator_by_name

The klass that is being searched.

Returns:

  • (Class, #search_operator_by_name)


44
45
46
# File 'app/models/metasploit/model/search/query.rb', line 44

def klass
  @klass
end

#operationsArray<Metasploit::Model::Search::Operation::Base>

Parses #formatted to create search operations that can validate if the value is correct the operation's operator's type.

Returns:



50
# File 'app/models/metasploit/model/search/query.rb', line 50

attr_writer :operations

Class Method Details

.formatted_operations(formatted) ⇒ Array<String>

Parses #formatted into a list of formatted operation composed of : Strings. may be quoted

Parameters:

  • formatted (String)

    a String composed of space-separated : operations. may be quoted using the shell quoting rules.

Returns:

  • (Array<String>)

    Array of formatted operation.

See Also:

  • Shellwords.shellsplit


76
77
78
# File 'app/models/metasploit/model/search/query.rb', line 76

def self.formatted_operations(formatted)
  Shellwords.shellsplit(formatted.to_s)
end

Instance Method Details

#operations_by_operatorHash{Metasploit::Model::Search::Operator::Base => Metasploit::Model::Search::Operation::Base}

Note:

Query is validated before grouping the operations as {Metasploit::Model::Search::Operation::Null operation

using unknown operators} with the same name should not be grouped together when processing this query into an actual search of record and/or models.

Groups #operations together by Operation::Base#operator.

Returns:

Raises:



114
115
116
117
118
119
120
121
122
# File 'app/models/metasploit/model/search/query.rb', line 114

def operations_by_operator
  unless instance_variable_defined? :@operations_by_operator
    valid!

    @operations_by_operator = operations.group_by(&:operator)
  end

  @operations_by_operator ||= operations.group_by(&:operator)
end

#operations_validvoid (private)

This method returns an undefined value.

Validates that all #operations are valid.



185
186
187
188
189
# File 'app/models/metasploit/model/search/query.rb', line 185

def operations_valid
  unless operations.all?(&:valid?)
    errors.add(:operations, :invalid)
  end
end

#parse_operator(formatted_operator) ⇒ Metasploit::Model::Search::Operation::Base, Metasploit::Model::Search::Operator::Null

Converts formatted operator extracted from formatted operation to its Operator::Base instance.

Parameters:

  • formatted_operator (#to_sym)

    formatted operator as parsed from formatted operation.

Returns:



132
133
134
135
136
137
138
139
140
141
# File 'app/models/metasploit/model/search/query.rb', line 132

def parse_operator(formatted_operator)
  operator_name = formatted_operator.to_sym
  operator = klass.search_operator_by_name[operator_name]

  unless operator
    operator = Metasploit::Model::Search::Operator::Null.new(:name => operator_name)
  end

  operator
end

#treeMetasploit::Model::Search::Group::Intersection<Metasploit::Model::Search::Group::Union<Metasploit::Model::Search::Operation::Base>>

Groups #operations together by Operation::Base#operator into unions that are intersected.



148
149
150
151
152
153
154
155
156
157
158
# File 'app/models/metasploit/model/search/query.rb', line 148

def tree
  unless instance_variable_defined? :@tree
    unions = operations_by_operator.collect do |_operator, operations|
      Metasploit::Model::Search::Group::Union.new(:children => operations)
    end

    @tree = Metasploit::Model::Search::Group::Intersection.new(:children => unions)
  end

  @tree
end

#without_operator(operator) ⇒ Metasploit::Model:Search::Query

Returns a new query with all #operations on the given operator removed.

Parameters:

Returns:

  • (Metasploit::Model:Search::Query)

    a new query if operator is a key in #operations_by_operator; otherwise this query.



165
166
167
168
169
170
171
172
173
174
175
176
177
178
# File 'app/models/metasploit/model/search/query.rb', line 165

def without_operator(operator)
  operations = operations_by_operator[operator]

  if operations
    filtered_operations = self.operations - operations

    self.class.new(
        klass: klass,
        operations: filtered_operations
    )
  else
    self
  end
end