metasploit-model 0.25.7 → 0.26.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
|