metasploit-model 0.25.7 → 0.26.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +8 -8
- data/app/models/metasploit/model/search/operation/association.rb +57 -0
- data/app/models/metasploit/model/search/operator/association.rb +24 -14
- data/app/models/metasploit/model/search/operator/base.rb +19 -3
- data/app/models/metasploit/model/search/operator/single.rb +21 -1
- data/app/models/metasploit/model/search/query.rb +20 -1
- data/lib/metasploit/model/association/tree.rb +130 -0
- data/lib/metasploit/model/search.rb +61 -27
- data/lib/metasploit/model/search/association.rb +152 -8
- data/lib/metasploit/model/search/attribute.rb +112 -22
- data/lib/metasploit/model/search/operator.rb +53 -1
- data/lib/metasploit/model/search/operator/help.rb +39 -1
- data/lib/metasploit/model/search/with.rb +44 -1
- data/lib/metasploit/model/version.rb +2 -2
- data/spec/app/models/metasploit/model/search/operation/association_spec.rb +67 -0
- data/spec/app/models/metasploit/model/search/operator/association_spec.rb +76 -76
- data/spec/app/models/metasploit/model/search/operator/deprecated/author_spec.rb +54 -18
- data/spec/app/models/metasploit/model/search/operator/deprecated/authority_spec.rb +20 -8
- data/spec/app/models/metasploit/model/search/operator/deprecated/platform_spec.rb +20 -8
- data/spec/app/models/metasploit/model/search/operator/deprecated/ref_spec.rb +86 -26
- data/spec/app/models/metasploit/model/search/operator/deprecated/text_spec.rb +63 -21
- data/spec/lib/metasploit/model/search/association/tree_spec.rb +385 -0
- data/spec/lib/metasploit/model/search/association_spec.rb +99 -10
- data/spec/lib/metasploit/model/search_spec.rb +48 -107
- data/spec/support/shared/examples/search/query/metasploit/model/search/operator/deprecated/authority.rb +19 -7
- metadata +7 -1
@@ -1,29 +1,173 @@
|
|
1
1
|
module Metasploit
|
2
2
|
module Model
|
3
3
|
module Search
|
4
|
-
#
|
4
|
+
# Use search operators registered on an associated class using
|
5
|
+
# {Metasploit::Model::Search::Attribute::ClassMethods#search_attribute},
|
6
|
+
# {Metasploit::Model::Search::With::ClassMethods#search_with}.
|
7
|
+
#
|
8
|
+
# Searchable associations are declared explicitly so that associations cycles can be avoided and the search
|
9
|
+
# interface can be tuned for clarity and complexity.
|
10
|
+
#
|
11
|
+
# # Testing
|
12
|
+
#
|
13
|
+
# {ClassMethods#search_association} calls can be tested with the 'search_association' shared example. First,
|
14
|
+
# ensure the shared examples from `metasploit-model` are required in your `spec_helper.rb`:
|
15
|
+
#
|
16
|
+
# # spec/spec_helper.rb
|
17
|
+
# support_glob = Metasploit::Model::Engine.root.join('spec', 'support', '**', '*.rb')
|
18
|
+
#
|
19
|
+
# Dir.glob(support_glob) do |path|
|
20
|
+
# require path
|
21
|
+
# end
|
22
|
+
#
|
23
|
+
# In the spec for the `Class` that called `search_association`, use the 'search_association' shared example:
|
24
|
+
#
|
25
|
+
# # spec/app/models/my_class_spec.rb
|
26
|
+
# require 'spec_helper'
|
27
|
+
#
|
28
|
+
# describe MyClass do
|
29
|
+
# context 'search' do
|
30
|
+
# context 'associations' do
|
31
|
+
# it_should_be_like 'search_association', :association_name
|
32
|
+
# end
|
33
|
+
# end
|
34
|
+
# end
|
35
|
+
#
|
36
|
+
# @example Search near and far associations
|
37
|
+
# class Root
|
38
|
+
# include Metasploit::Model::Association
|
39
|
+
# include Metasploit::Model::Search
|
40
|
+
#
|
41
|
+
# #
|
42
|
+
# # Associations
|
43
|
+
# #
|
44
|
+
#
|
45
|
+
# association :children,
|
46
|
+
# class_name: 'Child'
|
47
|
+
#
|
48
|
+
# #
|
49
|
+
# # Search
|
50
|
+
# #
|
51
|
+
#
|
52
|
+
# search_association children: :grandchildren
|
53
|
+
# end
|
54
|
+
#
|
55
|
+
# class Child
|
56
|
+
# include Metasploit::Model::Association
|
57
|
+
# include Metasploit::Model::Search
|
58
|
+
#
|
59
|
+
# #
|
60
|
+
# # Associations
|
61
|
+
# #
|
62
|
+
#
|
63
|
+
# association :grandchildren,
|
64
|
+
# class_name: 'Grandchild'
|
65
|
+
#
|
66
|
+
# #
|
67
|
+
# # Search
|
68
|
+
# #
|
69
|
+
#
|
70
|
+
# search_attribute :name,
|
71
|
+
# type: :string
|
72
|
+
# end
|
73
|
+
#
|
74
|
+
# class Grandchild
|
75
|
+
# include Metasploit::Model::Search
|
76
|
+
#
|
77
|
+
# search_attribute :age,
|
78
|
+
# type: :integer
|
79
|
+
# end
|
80
|
+
#
|
81
|
+
# Root.search_operator_by_name.each_value
|
82
|
+
# # :'children.name'
|
83
|
+
# # :'children.grandchildren.age'
|
84
|
+
#
|
85
|
+
# Child.search_operator_by_name.each_value
|
86
|
+
# # :name
|
87
|
+
# # @note ``:'grandchildren.age'`` is not in `Child`'s operators because it didn't declare
|
88
|
+
# # `search_association :grandchildren`, only `Root` did.
|
89
|
+
#
|
90
|
+
# Grandchild.search_operator_name
|
91
|
+
# # :age
|
92
|
+
#
|
5
93
|
module Association
|
6
94
|
extend ActiveSupport::Concern
|
7
95
|
|
8
96
|
# Adds {#search_association} DSL to make {Metasploit::Model::Search::Operator::Association association search
|
9
97
|
# operators}.
|
10
98
|
module ClassMethods
|
99
|
+
# @note Use {#search_associations} to declare multiple associations or a tree of far associations as
|
100
|
+
# searchable.
|
101
|
+
#
|
11
102
|
# Registers association for search.
|
12
103
|
#
|
104
|
+
# @example a single searchable association
|
105
|
+
# search_association :children
|
106
|
+
#
|
13
107
|
# @param association [#to_sym] name of association to search.
|
14
108
|
# @return [void]
|
109
|
+
# @see #search_associations
|
15
110
|
def search_association(association)
|
16
|
-
|
111
|
+
search_association_tree[association.to_sym] ||= nil
|
17
112
|
end
|
18
113
|
|
19
|
-
#
|
114
|
+
# Registers a tree of near and far associations for search. When a tree is used, all intermediate association
|
115
|
+
# on the paths are used, so `search_association children: :grandchildren` makes both `children.granchildren`
|
116
|
+
# *and* `children` as search operator prefixes.
|
117
|
+
#
|
118
|
+
# @example a single search association
|
119
|
+
# search_associations :children
|
120
|
+
#
|
121
|
+
# @example multiple near associations
|
122
|
+
# search_associations :first,
|
123
|
+
# :second
|
124
|
+
#
|
125
|
+
# @example far association
|
126
|
+
# search_associations near: :far
|
127
|
+
#
|
128
|
+
# @example multiple far associations
|
129
|
+
# search_associations near: [
|
130
|
+
# :first_far,
|
131
|
+
# :second_far
|
132
|
+
# ]
|
133
|
+
#
|
134
|
+
# @example mix of near and far associations
|
135
|
+
# # Keep associations in order by near association names by mixing Symbols and Hash{Symbol => Object}
|
136
|
+
# search_associations :apple,
|
137
|
+
# {
|
138
|
+
# banana: :peel
|
139
|
+
# },
|
140
|
+
# :cucumber
|
141
|
+
#
|
20
142
|
#
|
21
|
-
# @
|
22
|
-
#
|
143
|
+
# @param associations [Array<Array, Hash, Symbol>, Hash, Symbol]
|
144
|
+
# @return [void]
|
145
|
+
# @see search_association
|
146
|
+
def search_associations(*associations)
|
147
|
+
expanded_associations = Metasploit::Model::Association::Tree.expand(associations)
|
148
|
+
|
149
|
+
@search_association_tree = Metasploit::Model::Association::Tree.merge(
|
150
|
+
search_association_tree,
|
151
|
+
expanded_associations
|
152
|
+
)
|
153
|
+
end
|
154
|
+
|
155
|
+
# The association operators for the searchable associations declared with {#search_association} and
|
156
|
+
# {#search_associations}.
|
157
|
+
#
|
158
|
+
# @return (see Metasploit::Model::Association::Tree.operators)
|
159
|
+
def search_association_operators
|
160
|
+
@search_association_operators ||= Metasploit::Model::Association::Tree.operators(
|
161
|
+
search_association_tree,
|
162
|
+
class: self
|
163
|
+
)
|
164
|
+
end
|
165
|
+
|
166
|
+
# Tree of associations that are searchable.
|
23
167
|
#
|
24
|
-
# @return [
|
25
|
-
def
|
26
|
-
@
|
168
|
+
# @return [Hash{Symbol => Hash,nil}]
|
169
|
+
def search_association_tree
|
170
|
+
@search_association_tree ||= {}
|
27
171
|
end
|
28
172
|
end
|
29
173
|
end
|
@@ -1,7 +1,117 @@
|
|
1
1
|
module Metasploit
|
2
2
|
module Model
|
3
3
|
module Search
|
4
|
-
# Registers attributes that can be searched.
|
4
|
+
# Registers attributes that can be searched. Attributes must be declared to be searchable as a type from
|
5
|
+
# {Metasploit::Model::Search::Operator::Attribute::TYPES}. The type of the attribute is used to select a
|
6
|
+
# type-specific {Metasploit::Model::Search::Operation}, which will validate the
|
7
|
+
# {Metasploit::Model::Search::Operation::Base#value} is of the valid type.
|
8
|
+
#
|
9
|
+
# # Set attributes
|
10
|
+
#
|
11
|
+
# Search attributes declared as having an integer set or string set type integer or string set require a
|
12
|
+
# `<attribute>_set` method to be defined on the `Class`, which returns the set of allowed values for the search
|
13
|
+
# attribute's operation. This method will be called, indirectly by
|
14
|
+
# {Metasploit::Model::Search::Operation::Set::Integer}'s and {Metasploit::Model::Search::Operation::Set::String}'s
|
15
|
+
# validations.
|
16
|
+
#
|
17
|
+
# # Help
|
18
|
+
#
|
19
|
+
# The help for each operator is uses the `I18n` system, so the help for an attribute operator on a given class can
|
20
|
+
# added to `config/locales/<lang>.yml`. The scope of the lookup, under the language key is the `Class`'s
|
21
|
+
# `i18n_scope`, which is `metasploit.model` if the `Class` includes {Metasploit::Model::Translation} or
|
22
|
+
# `active_record` for `ActiveRecord::Base` subclasses. Under the `i18n_scope`, any `Module#ancestor`'s
|
23
|
+
# `model_name.i18n_key` can be used to look up the help for an attribute's operator. This allows for super
|
24
|
+
# classes or mixins to define the search operator help for subclasses.
|
25
|
+
#
|
26
|
+
# # config/locales/<lang>.yml
|
27
|
+
# <lang>:
|
28
|
+
# <Class#i18n_scope>:
|
29
|
+
# ancestors:
|
30
|
+
# <ancestor.model_name.i18n_key>:
|
31
|
+
# search:
|
32
|
+
# operator:
|
33
|
+
# names:
|
34
|
+
# <attribute>:
|
35
|
+
# help: "The attribute on the class"
|
36
|
+
#
|
37
|
+
# # Testing
|
38
|
+
#
|
39
|
+
# {ClassMethods#search_attribute} calls can be tested with the 'search_attribute' shared example. First, ensure
|
40
|
+
# the shared examples from `metasploit-model` are required in your `spec_helper.rb`:
|
41
|
+
#
|
42
|
+
# # spec/spec_helper.rb
|
43
|
+
# support_glob = Metasploit::Model::Engine.root.join('spec', 'support', '**', '*.rb')
|
44
|
+
#
|
45
|
+
# Dir.glob(support_glob) do |path|
|
46
|
+
# require path
|
47
|
+
# end
|
48
|
+
#
|
49
|
+
# In the spec for the `Class` that called `search_attribute`, use the 'search_attribute' shared example by
|
50
|
+
# passing that arguments passed to {ClassMethods#search_attribute}.
|
51
|
+
#
|
52
|
+
# # spec/app/models/my_class_spec.rb
|
53
|
+
# require 'spec_helper'
|
54
|
+
#
|
55
|
+
# describe MyClass do
|
56
|
+
# context 'search' do
|
57
|
+
# context 'attributes' do
|
58
|
+
# it_should_behave_like 'search_attribute',
|
59
|
+
# type: {
|
60
|
+
# set: :string
|
61
|
+
# }
|
62
|
+
# end
|
63
|
+
# end
|
64
|
+
# end
|
65
|
+
#
|
66
|
+
# @example search an attribute for `true` or `false`
|
67
|
+
# search_attribute :flag,
|
68
|
+
# type: :boolean
|
69
|
+
#
|
70
|
+
# @example search an attribute for an integer
|
71
|
+
# search_attribute :age,
|
72
|
+
# type: :integer
|
73
|
+
#
|
74
|
+
# @example search an attribute for a restricted set of integers
|
75
|
+
# #
|
76
|
+
# # Search
|
77
|
+
# #
|
78
|
+
#
|
79
|
+
# search_attribute :bits,
|
80
|
+
# set: :integer
|
81
|
+
#
|
82
|
+
# #
|
83
|
+
# # Class Methods
|
84
|
+
# #
|
85
|
+
#
|
86
|
+
# # Return set of allowed values for {#bits} search.
|
87
|
+
# #
|
88
|
+
# # @return [Set<Integer>]
|
89
|
+
# def self.bits_set
|
90
|
+
# @bits_set ||= Set.new([32, 64])
|
91
|
+
# end
|
92
|
+
#
|
93
|
+
# @example search an attribute for a restricted set of strings
|
94
|
+
# #
|
95
|
+
# # Search
|
96
|
+
# #
|
97
|
+
#
|
98
|
+
# search_attribute :endianness,
|
99
|
+
# set: :string
|
100
|
+
#
|
101
|
+
# #
|
102
|
+
# # Class Methods
|
103
|
+
# #
|
104
|
+
#
|
105
|
+
# # Return set of allowed values for {#endianness} search.
|
106
|
+
# #
|
107
|
+
# # @return [Set<String>]
|
108
|
+
# def self.endianness_set
|
109
|
+
# @endianness_set ||= Set.new(['big', 'litte'])
|
110
|
+
# end
|
111
|
+
#
|
112
|
+
# @example search an attribute by substring (case-insensitve LIKE)
|
113
|
+
# search_attribute :description,
|
114
|
+
# type: :string
|
5
115
|
module Attribute
|
6
116
|
extend ActiveSupport::Concern
|
7
117
|
|
@@ -10,27 +120,7 @@ module Metasploit
|
|
10
120
|
# Adds {#search_attribute} DSL to make {Metasploit::Model::Search::Operator::Attribute attribute search
|
11
121
|
# operators}.
|
12
122
|
module ClassMethods
|
13
|
-
#
|
14
|
-
#
|
15
|
-
# @example defining help
|
16
|
-
# # lib/metasploit/model/module/instance.rb
|
17
|
-
# module Metasploit::Model::Module::Instance
|
18
|
-
# include Metasploit::Model::Search
|
19
|
-
#
|
20
|
-
# included do
|
21
|
-
# search_attribute :description, :type => :string
|
22
|
-
# end
|
23
|
-
# end
|
24
|
-
#
|
25
|
-
# # config/locales/en.yml
|
26
|
-
# en:
|
27
|
-
# metasploit:
|
28
|
-
# model:
|
29
|
-
# module:
|
30
|
-
# instance:
|
31
|
-
# search_attribute:
|
32
|
-
# description:
|
33
|
-
# help: "A long, paragraph description of what the module does."
|
123
|
+
# {include:Metasploit::Model::Search::Attribute}
|
34
124
|
#
|
35
125
|
# @param attribute [#to_sym] name of attribute to search.
|
36
126
|
# @param options [Hash{Symbol => String}]
|
@@ -1,7 +1,59 @@
|
|
1
1
|
module Metasploit
|
2
2
|
module Model
|
3
3
|
module Search
|
4
|
-
#
|
4
|
+
# # Declaring operator classes
|
5
|
+
#
|
6
|
+
# ## Interface
|
7
|
+
#
|
8
|
+
# Operators do not need to subclass any specific superclass, but they are expected to define certain methods.
|
9
|
+
#
|
10
|
+
# class MyOperator
|
11
|
+
# #
|
12
|
+
# # Instance Methods
|
13
|
+
# #
|
14
|
+
#
|
15
|
+
# # @param klass [Class] The klass on which `search_with` was called.
|
16
|
+
# def initialize(attributes={})
|
17
|
+
# # ...
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
# # Description of what this operator searches for.
|
21
|
+
# #
|
22
|
+
# # @return [String]
|
23
|
+
# def help
|
24
|
+
# # ...
|
25
|
+
# end
|
26
|
+
#
|
27
|
+
# # Name of this operator. The name of the operator is matched to the string before the ':' in a formatted
|
28
|
+
# # operation.
|
29
|
+
# #
|
30
|
+
# # @return [Symbol]
|
31
|
+
# def name
|
32
|
+
# # ...
|
33
|
+
# end
|
34
|
+
#
|
35
|
+
# # Creates a one or more operations based on `formatted_value`.
|
36
|
+
# #
|
37
|
+
# # @return [#operator, Array<#operator>] Operation with this operator as the operation's `operator`.
|
38
|
+
# def operate_on(formatted_value)
|
39
|
+
# # ...
|
40
|
+
# end
|
41
|
+
# end
|
42
|
+
#
|
43
|
+
# ## Help
|
44
|
+
#
|
45
|
+
# Instead of having define your own `#help` method for your operator `Class`, you can `include`
|
46
|
+
# {Metasploit::Model::Search::Operator::Help}.
|
47
|
+
#
|
48
|
+
# {include:Metasploit::Model::Search::Operator::Help}
|
49
|
+
#
|
50
|
+
# ## {Metasploit::Model::Search::Operator::Base}
|
51
|
+
#
|
52
|
+
# {include:Metasploit::Model::Search::Operator::Base}
|
53
|
+
#
|
54
|
+
# ## {Metasploit::Model::Search::Operator::Single}
|
55
|
+
#
|
56
|
+
# {include:Metasploit::Model::Search::Operator::Single}
|
5
57
|
module Operator
|
6
58
|
|
7
59
|
end
|
@@ -2,7 +2,45 @@ module Metasploit
|
|
2
2
|
module Model
|
3
3
|
module Search
|
4
4
|
module Operator
|
5
|
-
#
|
5
|
+
# This allows the help to be looked up using `I18n`, and for the
|
6
|
+
# help to be customized based on the following criteria:
|
7
|
+
#
|
8
|
+
# `klass` on which the operator is declared, including any `Module#ancestors` and the operator `name`
|
9
|
+
#
|
10
|
+
# # config/locales/<lang>.yml
|
11
|
+
# <lang>:
|
12
|
+
# <klass.i18n_scope>:
|
13
|
+
# ancestors:
|
14
|
+
# <klass_ancestor.model_name.i18n_key>:
|
15
|
+
# search:
|
16
|
+
# operator:
|
17
|
+
# names:
|
18
|
+
# <name>:
|
19
|
+
# help: "Help for searching <name> on <klass>"
|
20
|
+
#
|
21
|
+
# `class` of the operator, including any `Module#ancestors` and the operator `name`
|
22
|
+
#
|
23
|
+
# # config/locales/<lang>.yml
|
24
|
+
# <lang>:
|
25
|
+
# <operator.class.i18n_scope>:
|
26
|
+
# search:
|
27
|
+
# operator:
|
28
|
+
# ancestors:
|
29
|
+
# <operator_class_ancestor.model_name.i18n_key>:
|
30
|
+
# <name>:
|
31
|
+
# help: "Help for searching <name> using <operator.class>"
|
32
|
+
#
|
33
|
+
# `class` of the operator, including any `Module#ancestors` without the operator `name`
|
34
|
+
#
|
35
|
+
# # config/locales/<lang>.yml
|
36
|
+
# <lang>:
|
37
|
+
# <operator.class.i18n_scope>:
|
38
|
+
# search:
|
39
|
+
# operator:
|
40
|
+
# ancestors:
|
41
|
+
# <operator_class_ancestor.model_name.i18n_key>:
|
42
|
+
# help: "Help for searching using <operator.class>"
|
43
|
+
#
|
6
44
|
module Help
|
7
45
|
# @note This uses I18n.translate along with {Metasploit::Model::Translation#search_i18n_scope},
|
8
46
|
# the value is not cached to support changing the I18n.locale and getting the correct help message for that
|
@@ -1,7 +1,50 @@
|
|
1
1
|
module Metasploit
|
2
2
|
module Model
|
3
3
|
module Search
|
4
|
-
# Generalizes operators from attributes to anything directly registered as
|
4
|
+
# Generalizes {Metasploit::Model::Search::Attribute operators from attributes} to anything directly registered as
|
5
|
+
# an operator on a class.
|
6
|
+
#
|
7
|
+
# {include:Metasploit::Model::Search::Operator}
|
8
|
+
#
|
9
|
+
# # Testing
|
10
|
+
#
|
11
|
+
# {ClassMethods#search_with} calls can be tested with the 'search_with' shared example. First, ensure
|
12
|
+
# the shared examples from `metasploit-model` are required in your `spec_helper.rb`:
|
13
|
+
#
|
14
|
+
# # spec/spec_helper.rb
|
15
|
+
# support_glob = Metasploit::Model::Engine.root.join('spec', 'support', '**', '*.rb')
|
16
|
+
#
|
17
|
+
# Dir.glob(support_glob) do |path|
|
18
|
+
# require path
|
19
|
+
# end
|
20
|
+
#
|
21
|
+
# In the spec fo the `Class` that called `search_with`, use the 'search_with' shared example by passing the
|
22
|
+
# arguments passed to {ClassMethods#search_attribute}.
|
23
|
+
#
|
24
|
+
# # app/models/my_class.rb
|
25
|
+
# class MyClass
|
26
|
+
# include Metasploit::Model::Search
|
27
|
+
#
|
28
|
+
# #
|
29
|
+
# # Search
|
30
|
+
# #
|
31
|
+
#
|
32
|
+
# search_with MyOperatorClass,
|
33
|
+
# foo: :bar
|
34
|
+
# end
|
35
|
+
#
|
36
|
+
# # spec/app/models/my_class_spec.rb
|
37
|
+
# require 'spec_helper'
|
38
|
+
#
|
39
|
+
# describe MyClass do
|
40
|
+
# context 'search' do
|
41
|
+
# context 'attributes' do
|
42
|
+
# it_should_behave_like 'search_with',
|
43
|
+
# MyOperatorClass,
|
44
|
+
# foo: :bar
|
45
|
+
# end
|
46
|
+
# end
|
47
|
+
# end
|
5
48
|
module With
|
6
49
|
extend ActiveSupport::Concern
|
7
50
|
|