metasploit_data_models 0.17.1 → 0.17.2.pre.metasploit.pre.data.pre.models.pre.search
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/.travis.yml +4 -0
 - data/Gemfile +2 -0
 - data/app/models/mdm/host.rb +24 -0
 - data/app/models/mdm/service.rb +9 -0
 - data/app/models/metasploit_data_models/search/visitor/attribute.rb +13 -0
 - data/app/models/metasploit_data_models/search/visitor/includes.rb +28 -0
 - data/app/models/metasploit_data_models/search/visitor/joins.rb +47 -0
 - data/app/models/metasploit_data_models/search/visitor/method.rb +13 -0
 - data/app/models/metasploit_data_models/search/visitor/relation.rb +87 -0
 - data/app/models/metasploit_data_models/search/visitor/where.rb +65 -0
 - data/config/locales/en.yml +7 -0
 - data/lib/metasploit_data_models.rb +1 -0
 - data/lib/metasploit_data_models/search.rb +6 -0
 - data/lib/metasploit_data_models/search/visitor.rb +8 -0
 - data/lib/metasploit_data_models/version.rb +1 -1
 - data/metasploit_data_models.gemspec +1 -0
 - data/spec/app/models/metasploit_data_models/search/visitor/attribute_spec.rb +74 -0
 - data/spec/app/models/metasploit_data_models/search/visitor/includes_spec.rb +124 -0
 - data/spec/app/models/metasploit_data_models/search/visitor/joins_spec.rb +292 -0
 - data/spec/app/models/metasploit_data_models/search/visitor/method_spec.rb +33 -0
 - data/spec/app/models/metasploit_data_models/search/visitor/relation_spec.rb +253 -0
 - data/spec/app/models/metasploit_data_models/search/visitor/where_spec.rb +147 -0
 - data/spec/dummy/config/initializers/active_record_migrations.rb +4 -0
 - data/spec/factories/mdm/services.rb +5 -0
 - data/spec/support/shared/examples/metasploit_data_models/search/visitor/includes/visit/with_children.rb +38 -0
 - data/spec/support/shared/examples/metasploit_data_models/search/visitor/includes/visit/with_metasploit_model_search_operation_base.rb +26 -0
 - data/spec/support/shared/examples/metasploit_data_models/search/visitor/relation/visit/matching_record.rb +37 -0
 - data/spec/support/shared/examples/metasploit_data_models/search/visitor/relation/visit/matching_record/with_metasploit_model_search_opeator_deprecated_platform.rb +31 -0
 - data/spec/support/shared/examples/metasploit_data_models/search/visitor/relation/visit/matching_record/with_metasploit_model_search_operator_deprecated_authority.rb +78 -0
 - data/spec/support/shared/examples/metasploit_data_models/search/visitor/where/visit/with_equality.rb +34 -0
 - data/spec/support/shared/examples/metasploit_data_models/search/visitor/where/visit/with_metasploit_model_search_group_base.rb +50 -0
 - metadata +61 -4
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,15 +1,15 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            !binary "U0hBMQ==":
         
     | 
| 
       3 
3 
     | 
    
         
             
              metadata.gz: !binary |-
         
     | 
| 
       4 
     | 
    
         
            -
                 
     | 
| 
      
 4 
     | 
    
         
            +
                ZTk1ODlmNzUyMDg2MjZlMjZkNzUyMWVmZWQ4NTVlMzhlZmU2OWM2OA==
         
     | 
| 
       5 
5 
     | 
    
         
             
              data.tar.gz: !binary |-
         
     | 
| 
       6 
     | 
    
         
            -
                 
     | 
| 
      
 6 
     | 
    
         
            +
                MDUzNTY1ZjRjNzU5NWYzOTMyODE1NGIxNzI0MzAwMjRlOWNjY2I2NQ==
         
     | 
| 
       7 
7 
     | 
    
         
             
            SHA512:
         
     | 
| 
       8 
8 
     | 
    
         
             
              metadata.gz: !binary |-
         
     | 
| 
       9 
     | 
    
         
            -
                 
     | 
| 
       10 
     | 
    
         
            -
                 
     | 
| 
       11 
     | 
    
         
            -
                 
     | 
| 
      
 9 
     | 
    
         
            +
                YTlhMTU5NTRiYTI5Y2YwZjYwOTMzNWIxN2NjOTY4YWVjNmE4Y2Q2OWFiNzc2
         
     | 
| 
      
 10 
     | 
    
         
            +
                YzQ4NTJhNDRlOGYzODdkNjQ4MDljNDJlZTZlNTIxZmFjMTk5YTdjODU4NGVj
         
     | 
| 
      
 11 
     | 
    
         
            +
                NjUzZTQyZTU1MmIzNGQ2NDg5MjdlZTk0MDJhM2Q4Mjc4MzY3NWI=
         
     | 
| 
       12 
12 
     | 
    
         
             
              data.tar.gz: !binary |-
         
     | 
| 
       13 
     | 
    
         
            -
                 
     | 
| 
       14 
     | 
    
         
            -
                 
     | 
| 
       15 
     | 
    
         
            -
                 
     | 
| 
      
 13 
     | 
    
         
            +
                NTFiMTFkODU2ZTZmZjE5ZGY1NjQwYjZkMDJkNjY2NjBlMGU4YzhmODQzNzJi
         
     | 
| 
      
 14 
     | 
    
         
            +
                NWRjY2M5MjI4NDhhM2ZiM2ZmZGRhNWNhZjRlNDBhNzc0ODY3OTRkNjI0NzE3
         
     | 
| 
      
 15 
     | 
    
         
            +
                MWIyZDUyZjg3NWU2NzEwMWVkMjc0MTYwNzMwZWMyYjQ0ZGFkNzQ=
         
     | 
    
        data/.travis.yml
    CHANGED
    
    | 
         @@ -2,6 +2,10 @@ before_script: 
     | 
|
| 
       2 
2 
     | 
    
         
             
              - cp spec/dummy/config/database.yml.travis spec/dummy/config/database.yml
         
     | 
| 
       3 
3 
     | 
    
         
             
              - rake db:setup
         
     | 
| 
       4 
4 
     | 
    
         
             
            language: ruby
         
     | 
| 
      
 5 
     | 
    
         
            +
            matrix:
         
     | 
| 
      
 6 
     | 
    
         
            +
              allow_failures:
         
     | 
| 
      
 7 
     | 
    
         
            +
                # Rubinius.mri_backtrace primitive failed (PrimitiveFailure)
         
     | 
| 
      
 8 
     | 
    
         
            +
                - rvm: 'rbx-2.2'
         
     | 
| 
       5 
9 
     | 
    
         
             
            rvm:
         
     | 
| 
       6 
10 
     | 
    
         
             
              - '1.9.3'
         
     | 
| 
       7 
11 
     | 
    
         
             
              - '2.0'
         
     | 
    
        data/Gemfile
    CHANGED
    
    | 
         @@ -32,6 +32,8 @@ group :test do 
     | 
|
| 
       32 
32 
     | 
    
         
             
              gem 'shoulda-matchers'
         
     | 
| 
       33 
33 
     | 
    
         
             
              # code coverage of tests
         
     | 
| 
       34 
34 
     | 
    
         
             
              gem 'simplecov', :require => false
         
     | 
| 
      
 35 
     | 
    
         
            +
              # @todo Update specs for rspec 3.0.0 compatibility and remove this gem in favor of just rspec-rails
         
     | 
| 
      
 36 
     | 
    
         
            +
              gem 'rspec-core', '< 3.0.0'
         
     | 
| 
       35 
37 
     | 
    
         
             
              # need rspec-rails >= 2.12.0 as 2.12.0 adds support for redefining named subject in nested context that uses the
         
     | 
| 
       36 
38 
     | 
    
         
             
              # named subject from the outer context without causing a stack overflow.
         
     | 
| 
       37 
39 
     | 
    
         
             
              gem 'rspec-rails', '>= 2.12.0'
         
     | 
    
        data/app/models/mdm/host.rb
    CHANGED
    
    | 
         @@ -1,6 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # A system with an {#address IP address} on the network that has been discovered in some way.
         
     | 
| 
       2 
2 
     | 
    
         
             
            class Mdm::Host < ActiveRecord::Base
         
     | 
| 
       3 
3 
     | 
    
         
             
              include Mdm::Host::OperatingSystemNormalization
         
     | 
| 
      
 4 
     | 
    
         
            +
              include Metasploit::Model::Search
         
     | 
| 
       4 
5 
     | 
    
         | 
| 
       5 
6 
     | 
    
         
             
              #
         
     | 
| 
       6 
7 
     | 
    
         
             
              # CONSTANTS
         
     | 
| 
         @@ -462,6 +463,29 @@ class Mdm::Host < ActiveRecord::Base 
     | 
|
| 
       462 
463 
     | 
    
         
             
              scope :tag_search,
         
     | 
| 
       463 
464 
     | 
    
         
             
                    lambda { |*args| where("tags.name" => args[0]).includes(:tags) }
         
     | 
| 
       464 
465 
     | 
    
         | 
| 
      
 466 
     | 
    
         
            +
              #
         
     | 
| 
      
 467 
     | 
    
         
            +
              #
         
     | 
| 
      
 468 
     | 
    
         
            +
              # Search
         
     | 
| 
      
 469 
     | 
    
         
            +
              #
         
     | 
| 
      
 470 
     | 
    
         
            +
              #
         
     | 
| 
      
 471 
     | 
    
         
            +
             
     | 
| 
      
 472 
     | 
    
         
            +
              #
         
     | 
| 
      
 473 
     | 
    
         
            +
              # Search Associations
         
     | 
| 
      
 474 
     | 
    
         
            +
              #
         
     | 
| 
      
 475 
     | 
    
         
            +
             
     | 
| 
      
 476 
     | 
    
         
            +
              search_association :services
         
     | 
| 
      
 477 
     | 
    
         
            +
             
     | 
| 
      
 478 
     | 
    
         
            +
              #
         
     | 
| 
      
 479 
     | 
    
         
            +
              # Search Attributes
         
     | 
| 
      
 480 
     | 
    
         
            +
              #
         
     | 
| 
      
 481 
     | 
    
         
            +
             
     | 
| 
      
 482 
     | 
    
         
            +
              search_attribute :name,
         
     | 
| 
      
 483 
     | 
    
         
            +
                               type: :string
         
     | 
| 
      
 484 
     | 
    
         
            +
             
     | 
| 
      
 485 
     | 
    
         
            +
              #
         
     | 
| 
      
 486 
     | 
    
         
            +
              # Instance Methods
         
     | 
| 
      
 487 
     | 
    
         
            +
              #
         
     | 
| 
      
 488 
     | 
    
         
            +
             
     | 
| 
       465 
489 
     | 
    
         
             
              # Returns whether 'host.updated.<attr>' {#notes note} is {Mdm::Note#data locked}.
         
     | 
| 
       466 
490 
     | 
    
         
             
              #
         
     | 
| 
       467 
491 
     | 
    
         
             
              # @return [true] if Mdm::Note with 'host.updated.<attr>' as {Mdm::Note#name} exists and data[:locked] is `true`.
         
     | 
    
        data/app/models/mdm/service.rb
    CHANGED
    
    | 
         @@ -1,5 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # A service, such as an ssh server or web server, running on a {#host}.
         
     | 
| 
       2 
2 
     | 
    
         
             
            class Mdm::Service < ActiveRecord::Base
         
     | 
| 
      
 3 
     | 
    
         
            +
              include Metasploit::Model::Search
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
       3 
5 
     | 
    
         
             
              #
         
     | 
| 
       4 
6 
     | 
    
         
             
              # CONSTANTS
         
     | 
| 
       5 
7 
     | 
    
         
             
              #
         
     | 
| 
         @@ -174,6 +176,13 @@ class Mdm::Service < ActiveRecord::Base 
     | 
|
| 
       174 
176 
     | 
    
         
             
                      ])
         
     | 
| 
       175 
177 
     | 
    
         
             
              }
         
     | 
| 
       176 
178 
     | 
    
         | 
| 
      
 179 
     | 
    
         
            +
              #
         
     | 
| 
      
 180 
     | 
    
         
            +
              # Search Attributes
         
     | 
| 
      
 181 
     | 
    
         
            +
              #
         
     | 
| 
      
 182 
     | 
    
         
            +
             
     | 
| 
      
 183 
     | 
    
         
            +
              search_attribute :name,
         
     | 
| 
      
 184 
     | 
    
         
            +
                               type: :string
         
     | 
| 
      
 185 
     | 
    
         
            +
             
     | 
| 
       177 
186 
     | 
    
         
             
              #
         
     | 
| 
       178 
187 
     | 
    
         
             
              # Validations
         
     | 
| 
       179 
188 
     | 
    
         
             
              #
         
     | 
| 
         @@ -0,0 +1,13 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # Extracts the `Arel::Attribute` objects from `Metasploit::Model::Search::Operator::Base` subclasses.
         
     | 
| 
      
 2 
     | 
    
         
            +
            class MetasploitDataModels::Search::Visitor::Attribute
         
     | 
| 
      
 3 
     | 
    
         
            +
              include Metasploit::Model::Visitation::Visit
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
              visit 'Metasploit::Model::Search::Operator::Association' do |operator|
         
     | 
| 
      
 6 
     | 
    
         
            +
                visit operator.attribute_operator
         
     | 
| 
      
 7 
     | 
    
         
            +
              end
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
              visit 'Metasploit::Model::Search::Operator::Attribute' do |operator|
         
     | 
| 
      
 10 
     | 
    
         
            +
                table = operator.klass.arel_table
         
     | 
| 
      
 11 
     | 
    
         
            +
                table[operator.attribute]
         
     | 
| 
      
 12 
     | 
    
         
            +
              end
         
     | 
| 
      
 13 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,28 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # Gathers all the association names to pass to `ActiveRecord::Relation#includes` from a
         
     | 
| 
      
 2 
     | 
    
         
            +
            # `Metasploit::Model::Search::Query`
         
     | 
| 
      
 3 
     | 
    
         
            +
            class MetasploitDataModels::Search::Visitor::Includes
         
     | 
| 
      
 4 
     | 
    
         
            +
              include Metasploit::Model::Visitation::Visit
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
              #
         
     | 
| 
      
 7 
     | 
    
         
            +
              # Visitors
         
     | 
| 
      
 8 
     | 
    
         
            +
              #
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
              visit 'Metasploit::Model::Search::Group::Base',
         
     | 
| 
      
 11 
     | 
    
         
            +
                    'Metasploit::Model::Search::Operation::Union' do |parent|
         
     | 
| 
      
 12 
     | 
    
         
            +
                parent.children.flat_map { |child|
         
     | 
| 
      
 13 
     | 
    
         
            +
                  visit child
         
     | 
| 
      
 14 
     | 
    
         
            +
                }
         
     | 
| 
      
 15 
     | 
    
         
            +
            	end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
              visit 'Metasploit::Model::Search::Operation::Base' do |operation|
         
     | 
| 
      
 18 
     | 
    
         
            +
                visit operation.operator
         
     | 
| 
      
 19 
     | 
    
         
            +
              end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
              visit 'Metasploit::Model::Search::Operator::Association' do |operator|
         
     | 
| 
      
 22 
     | 
    
         
            +
                [operator.association]
         
     | 
| 
      
 23 
     | 
    
         
            +
              end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
              visit 'Metasploit::Model::Search::Operator::Attribute' do |_operator|
         
     | 
| 
      
 26 
     | 
    
         
            +
                []
         
     | 
| 
      
 27 
     | 
    
         
            +
              end
         
     | 
| 
      
 28 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,47 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # Gathers all the association names to pass to `ActiveRecord::Relation#joins` from a `Metasploit::Model::Search::Query`
         
     | 
| 
      
 2 
     | 
    
         
            +
            class MetasploitDataModels::Search::Visitor::Joins
         
     | 
| 
      
 3 
     | 
    
         
            +
              include Metasploit::Model::Visitation::Visit
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
              #
         
     | 
| 
      
 6 
     | 
    
         
            +
              # Visitors
         
     | 
| 
      
 7 
     | 
    
         
            +
              #
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
              visit 'Metasploit::Model::Search::Group::Intersection' do |parent|
         
     | 
| 
      
 10 
     | 
    
         
            +
                parent.children.flat_map { |child|
         
     | 
| 
      
 11 
     | 
    
         
            +
                  visit child
         
     | 
| 
      
 12 
     | 
    
         
            +
                }
         
     | 
| 
      
 13 
     | 
    
         
            +
              end
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
              visit 'Metasploit::Model::Search::Group::Union',
         
     | 
| 
      
 16 
     | 
    
         
            +
                    'Metasploit::Model::Search::Operation::Union' do |parent|
         
     | 
| 
      
 17 
     | 
    
         
            +
                # A Set<Set> because if all children have multiple joins, but those multiple joins contain the same elements for
         
     | 
| 
      
 18 
     | 
    
         
            +
                # all children, then all joins can be counted as common:
         
     | 
| 
      
 19 
     | 
    
         
            +
                #
         
     | 
| 
      
 20 
     | 
    
         
            +
                #  (a.b:1 && c.d:2) || (a.b:3 && c.d:4) should return [:a, :c] since its common to both
         
     | 
| 
      
 21 
     | 
    
         
            +
                #  (a.b:1 && c.d:2 && e.f:3) || (a.b:3 && c.d:4) should return [:a, :c] since its the common _subset_
         
     | 
| 
      
 22 
     | 
    
         
            +
                join_set_set = parent.children.each_with_object(Set.new) { |child, set|
         
     | 
| 
      
 23 
     | 
    
         
            +
                  child_joins = visit child
         
     | 
| 
      
 24 
     | 
    
         
            +
                  child_join_set = Set.new child_joins
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                  set.add child_join_set
         
     | 
| 
      
 27 
     | 
    
         
            +
                }
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                common_join_set = join_set_set.reduce { |common_subset, set|
         
     | 
| 
      
 30 
     | 
    
         
            +
                  common_subset & set
         
     | 
| 
      
 31 
     | 
    
         
            +
                }
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                common_join_set.to_a
         
     | 
| 
      
 34 
     | 
    
         
            +
              end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
              visit 'Metasploit::Model::Search::Operation::Base' do |operation|
         
     | 
| 
      
 37 
     | 
    
         
            +
                visit operation.operator
         
     | 
| 
      
 38 
     | 
    
         
            +
              end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
              visit 'Metasploit::Model::Search::Operator::Association' do |operator|
         
     | 
| 
      
 41 
     | 
    
         
            +
                [operator.association]
         
     | 
| 
      
 42 
     | 
    
         
            +
              end
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
              visit 'Metasploit::Model::Search::Operator::Attribute' do |_|
         
     | 
| 
      
 45 
     | 
    
         
            +
                []
         
     | 
| 
      
 46 
     | 
    
         
            +
              end
         
     | 
| 
      
 47 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,13 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # Extracts which AREL method to use as a translation for `Metasploit::Model::Search::Group::Base` subclasses.
         
     | 
| 
      
 2 
     | 
    
         
            +
            class MetasploitDataModels::Search::Visitor::Method
         
     | 
| 
      
 3 
     | 
    
         
            +
              include Metasploit::Model::Visitation::Visit
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
              visit 'Metasploit::Model::Search::Group::Intersection' do
         
     | 
| 
      
 6 
     | 
    
         
            +
                :and
         
     | 
| 
      
 7 
     | 
    
         
            +
              end
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
              visit 'Metasploit::Model::Search::Group::Union',
         
     | 
| 
      
 10 
     | 
    
         
            +
                    'Metasploit::Model::Search::Operation::Union' do
         
     | 
| 
      
 11 
     | 
    
         
            +
                :or
         
     | 
| 
      
 12 
     | 
    
         
            +
              end
         
     | 
| 
      
 13 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,87 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # Generates a `ActiveRecord::Relation` from an `Metasploit::Model::Search::Query#tree`
         
     | 
| 
      
 2 
     | 
    
         
            +
            class MetasploitDataModels::Search::Visitor::Relation < Metasploit::Model::Base
         
     | 
| 
      
 3 
     | 
    
         
            +
              #
         
     | 
| 
      
 4 
     | 
    
         
            +
              # CONSTANTS
         
     | 
| 
      
 5 
     | 
    
         
            +
              #
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
              # `ActiveRecord::Relation` methods that can compute their argument with a visitor under the
         
     | 
| 
      
 8 
     | 
    
         
            +
              # {MetasploitDataModels::Search::Visitor} namespace.
         
     | 
| 
      
 9 
     | 
    
         
            +
              RELATION_METHODS = [
         
     | 
| 
      
 10 
     | 
    
         
            +
                  :joins,
         
     | 
| 
      
 11 
     | 
    
         
            +
                  :includes,
         
     | 
| 
      
 12 
     | 
    
         
            +
                  :where
         
     | 
| 
      
 13 
     | 
    
         
            +
              ]
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
              #
         
     | 
| 
      
 16 
     | 
    
         
            +
              # Attributes
         
     | 
| 
      
 17 
     | 
    
         
            +
              #
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
              # @!attribute [rw] query
         
     | 
| 
      
 20 
     | 
    
         
            +
              #   The query to visit.  Query supplies Class with #scope upon which to build `ActiveRecord::Relation`.
         
     | 
| 
      
 21 
     | 
    
         
            +
              #
         
     | 
| 
      
 22 
     | 
    
         
            +
              #   @return [Metasploit::Model::Search::Query]
         
     | 
| 
      
 23 
     | 
    
         
            +
              attr_accessor :query
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
              #
         
     | 
| 
      
 26 
     | 
    
         
            +
              # Validations
         
     | 
| 
      
 27 
     | 
    
         
            +
              #
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
              validate :valid_query
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
              validates :query,
         
     | 
| 
      
 32 
     | 
    
         
            +
                        :presence => true
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
              #
         
     | 
| 
      
 35 
     | 
    
         
            +
              # Methods
         
     | 
| 
      
 36 
     | 
    
         
            +
              #
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
              # Visits {#query} tree to produce an `ActiveRecord::Relation` on the `Metasploit::Model::Search::Query#klass`.
         
     | 
| 
      
 39 
     | 
    
         
            +
              #
         
     | 
| 
      
 40 
     | 
    
         
            +
              # @return [ActiveRecord::Relation]
         
     | 
| 
      
 41 
     | 
    
         
            +
              def visit
         
     | 
| 
      
 42 
     | 
    
         
            +
                tree = query.tree
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                # Enumerable#inject does not support 3 arity for Hashes so need to unpack pair
         
     | 
| 
      
 45 
     | 
    
         
            +
                visitor_by_relation_method.inject(query.klass.scoped) do |relation, pair|
         
     | 
| 
      
 46 
     | 
    
         
            +
                  relation_method, visitor = pair
         
     | 
| 
      
 47 
     | 
    
         
            +
                  visited = visitor.visit(tree)
         
     | 
| 
      
 48 
     | 
    
         
            +
                  relation.send(relation_method, visited)
         
     | 
| 
      
 49 
     | 
    
         
            +
                end
         
     | 
| 
      
 50 
     | 
    
         
            +
              end
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
              # Map method on `ActiveRecord::Relation` to visitor that can visit `Metasploit::Model::Search::Query#tree` to
         
     | 
| 
      
 53 
     | 
    
         
            +
              # produce the arguments to the method on `ActiveRecord::Relation`.
         
     | 
| 
      
 54 
     | 
    
         
            +
              #
         
     | 
| 
      
 55 
     | 
    
         
            +
              # @return [Hash{Symbol => #visit}]
         
     | 
| 
      
 56 
     | 
    
         
            +
              def visitor_by_relation_method
         
     | 
| 
      
 57 
     | 
    
         
            +
                # Enumerable#each_with_object does not support 3 arity for Hashes so need to unpack pair
         
     | 
| 
      
 58 
     | 
    
         
            +
                @visitor_by_relation_method ||= self.class.visitor_class_by_relation_method.each_with_object({}) { |pair, visitor_by_relation_method|
         
     | 
| 
      
 59 
     | 
    
         
            +
                  relation_method, visitor_class = pair
         
     | 
| 
      
 60 
     | 
    
         
            +
                  visitor_by_relation_method[relation_method] = visitor_class.new
         
     | 
| 
      
 61 
     | 
    
         
            +
                }
         
     | 
| 
      
 62 
     | 
    
         
            +
              end
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
              # Maps method on `ActiveRecord::Relation` to the `Class` under {MetasploitDataModels::Search::Visitor} whose
         
     | 
| 
      
 65 
     | 
    
         
            +
              # `#visit` method can produce the arguments to the `ActiveRecord::Relation` method.
         
     | 
| 
      
 66 
     | 
    
         
            +
              #
         
     | 
| 
      
 67 
     | 
    
         
            +
              # @return [Hash{Symbol => Class}]
         
     | 
| 
      
 68 
     | 
    
         
            +
              def self.visitor_class_by_relation_method
         
     | 
| 
      
 69 
     | 
    
         
            +
                @relation_method_by_visitor_class ||= RELATION_METHODS.each_with_object({}) { |relation_method, relation_method_by_visitor_class|
         
     | 
| 
      
 70 
     | 
    
         
            +
                  visitor_class_name = "#{parent.name}::#{relation_method.to_s.camelize}"
         
     | 
| 
      
 71 
     | 
    
         
            +
                  visitor_class = visitor_class_name.constantize
         
     | 
| 
      
 72 
     | 
    
         
            +
             
     | 
| 
      
 73 
     | 
    
         
            +
                  relation_method_by_visitor_class[relation_method] = visitor_class
         
     | 
| 
      
 74 
     | 
    
         
            +
                }
         
     | 
| 
      
 75 
     | 
    
         
            +
              end
         
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
      
 77 
     | 
    
         
            +
              private
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
              # Validates that {#query} is valid.
         
     | 
| 
      
 80 
     | 
    
         
            +
              #
         
     | 
| 
      
 81 
     | 
    
         
            +
              # @return [void]
         
     | 
| 
      
 82 
     | 
    
         
            +
              def valid_query
         
     | 
| 
      
 83 
     | 
    
         
            +
                if query and !query.valid?
         
     | 
| 
      
 84 
     | 
    
         
            +
                  errors.add(:query, :invalid)
         
     | 
| 
      
 85 
     | 
    
         
            +
                end
         
     | 
| 
      
 86 
     | 
    
         
            +
              end
         
     | 
| 
      
 87 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,65 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # Generates AREL to pass to `ActiveRecord::Relation#where` from a `Metasploit::Model::Search::Query`.
         
     | 
| 
      
 2 
     | 
    
         
            +
            class MetasploitDataModels::Search::Visitor::Where
         
     | 
| 
      
 3 
     | 
    
         
            +
              include Metasploit::Model::Visitation::Visit
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
              #
         
     | 
| 
      
 6 
     | 
    
         
            +
              # CONSTANTS
         
     | 
| 
      
 7 
     | 
    
         
            +
              #
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
              # `Metasploit::Model::Search::Operation::Base` subclasses that check their value with the equality operator in
         
     | 
| 
      
 10 
     | 
    
         
            +
              # AREL
         
     | 
| 
      
 11 
     | 
    
         
            +
              EQUALITY_OPERATION_CLASS_NAMES = [
         
     | 
| 
      
 12 
     | 
    
         
            +
                  'Metasploit::Model::Search::Operation::Boolean',
         
     | 
| 
      
 13 
     | 
    
         
            +
                  'Metasploit::Model::Search::Operation::Date',
         
     | 
| 
      
 14 
     | 
    
         
            +
                  'Metasploit::Model::Search::Operation::Integer',
         
     | 
| 
      
 15 
     | 
    
         
            +
                  'Metasploit::Model::Search::Operation::Set'
         
     | 
| 
      
 16 
     | 
    
         
            +
              ]
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
              #
         
     | 
| 
      
 19 
     | 
    
         
            +
              # Visitor
         
     | 
| 
      
 20 
     | 
    
         
            +
              #
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
              visit 'Metasploit::Model::Search::Group::Base',
         
     | 
| 
      
 23 
     | 
    
         
            +
                    'Metasploit::Model::Search::Operation::Union' do |parent|
         
     | 
| 
      
 24 
     | 
    
         
            +
                method = method_visitor.visit parent
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                children_arel = parent.children.collect { |child|
         
     | 
| 
      
 27 
     | 
    
         
            +
                  visit child
         
     | 
| 
      
 28 
     | 
    
         
            +
                }
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                children_arel.inject { |group_arel, child_arel|
         
     | 
| 
      
 31 
     | 
    
         
            +
                  group_arel.send(method, child_arel)
         
     | 
| 
      
 32 
     | 
    
         
            +
                }
         
     | 
| 
      
 33 
     | 
    
         
            +
              end
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
              visit *EQUALITY_OPERATION_CLASS_NAMES do |operation|
         
     | 
| 
      
 36 
     | 
    
         
            +
                attribute = attribute_visitor.visit operation.operator
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                attribute.eq(operation.value)
         
     | 
| 
      
 39 
     | 
    
         
            +
              end
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
              visit 'Metasploit::Model::Search::Operation::String' do |operation|
         
     | 
| 
      
 42 
     | 
    
         
            +
                attribute = attribute_visitor.visit operation.operator
         
     | 
| 
      
 43 
     | 
    
         
            +
                match_value = "%#{operation.value}%"
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
                attribute.matches(match_value)
         
     | 
| 
      
 46 
     | 
    
         
            +
            	end
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
              #
         
     | 
| 
      
 49 
     | 
    
         
            +
              # Methods
         
     | 
| 
      
 50 
     | 
    
         
            +
              #
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
              # Visitor for `Metasploit::Model::Search::Operator::Base` subclasses to generate `Arel::Attributes::Attribute`.
         
     | 
| 
      
 53 
     | 
    
         
            +
              #
         
     | 
| 
      
 54 
     | 
    
         
            +
              # @return [MetasploitDataModels::Search::Visitor::Attribute]
         
     | 
| 
      
 55 
     | 
    
         
            +
              def attribute_visitor
         
     | 
| 
      
 56 
     | 
    
         
            +
                @attribute_visitor ||= MetasploitDataModels::Search::Visitor::Attribute.new
         
     | 
| 
      
 57 
     | 
    
         
            +
              end
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
              # Visitor for `Metasploit::Model::Search::Group::Base` subclasses to generate equivalent AREL node methods.
         
     | 
| 
      
 60 
     | 
    
         
            +
              #
         
     | 
| 
      
 61 
     | 
    
         
            +
              # @return [MetasploitDataModels::Search::Visitor::Method]
         
     | 
| 
      
 62 
     | 
    
         
            +
              def method_visitor
         
     | 
| 
      
 63 
     | 
    
         
            +
                @method_visitor ||= MetasploitDataModels::Search::Visitor::Method.new
         
     | 
| 
      
 64 
     | 
    
         
            +
              end
         
     | 
| 
      
 65 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -4,5 +4,5 @@ module MetasploitDataModels 
     | 
|
| 
       4 
4 
     | 
    
         
             
              # metasploit-framework/data/sql/migrate to db/migrate in this project, not all models have specs that verify the
         
     | 
| 
       5 
5 
     | 
    
         
             
              # migrations (with have_db_column and have_db_index) and certain models may not be shared between metasploit-framework
         
     | 
| 
       6 
6 
     | 
    
         
             
              # and pro, so models may be removed in the future.  Because of the unstable API the version should remain below 1.0.0
         
     | 
| 
       7 
     | 
    
         
            -
              VERSION = '0.17. 
     | 
| 
      
 7 
     | 
    
         
            +
              VERSION = '0.17.2-metasploit-data-models-search'
         
     | 
| 
       8 
8 
     | 
    
         
             
            end
         
     | 
| 
         @@ -38,6 +38,7 @@ Gem::Specification.new do |s| 
     | 
|
| 
       38 
38 
     | 
    
         
             
              # @see MSP-2971
         
     | 
| 
       39 
39 
     | 
    
         
             
              s.add_runtime_dependency 'activerecord', '>= 3.2.13', '< 4.0.0'
         
     | 
| 
       40 
40 
     | 
    
         
             
              s.add_runtime_dependency 'activesupport'
         
     | 
| 
      
 41 
     | 
    
         
            +
              s.add_runtime_dependency 'metasploit-model', '>= 0.24.1.pre.semantic.pre.versioning.pre.2.pre.0', '< 0.25'
         
     | 
| 
       41 
42 
     | 
    
         | 
| 
       42 
43 
     | 
    
         
             
              if RUBY_PLATFORM =~ /java/
         
     | 
| 
       43 
44 
     | 
    
         
             
                # markdown formatting for yard
         
     | 
| 
         @@ -0,0 +1,74 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'spec_helper'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            describe MetasploitDataModels::Search::Visitor::Attribute do
         
     | 
| 
      
 4 
     | 
    
         
            +
              subject(:visitor) do
         
     | 
| 
      
 5 
     | 
    
         
            +
                described_class.new
         
     | 
| 
      
 6 
     | 
    
         
            +
              end
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
              context '#visit' do
         
     | 
| 
      
 9 
     | 
    
         
            +
                subject(:visit) do
         
     | 
| 
      
 10 
     | 
    
         
            +
                  visitor.visit(node)
         
     | 
| 
      
 11 
     | 
    
         
            +
                end
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                context 'with Metasploit::Model::Search::Operator::Association' do
         
     | 
| 
      
 14 
     | 
    
         
            +
                  let(:attribute_operator) do
         
     | 
| 
      
 15 
     | 
    
         
            +
                    double('Attribute Operator')
         
     | 
| 
      
 16 
     | 
    
         
            +
                  end
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                  let(:node) do
         
     | 
| 
      
 19 
     | 
    
         
            +
                    Metasploit::Model::Search::Operator::Association.new(
         
     | 
| 
      
 20 
     | 
    
         
            +
                        :attribute_operator => attribute_operator
         
     | 
| 
      
 21 
     | 
    
         
            +
                    )
         
     | 
| 
      
 22 
     | 
    
         
            +
                  end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                  it 'should visit Metasploit::Model::Search::Operator::Association#attribute_operator' do
         
     | 
| 
      
 25 
     | 
    
         
            +
                    visitor.should_receive(:visit).with(node).and_call_original
         
     | 
| 
      
 26 
     | 
    
         
            +
                    visitor.should_receive(:visit).with(attribute_operator)
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
                    visit
         
     | 
| 
      
 29 
     | 
    
         
            +
                  end
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                  it 'should return visit of Metasploit::Model::Search::Operator::Association#attribute_operator' do
         
     | 
| 
      
 32 
     | 
    
         
            +
                    visitor.should_receive(:visit).with(node).and_call_original
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                    visited = double('Attribute Operator Visited')
         
     | 
| 
      
 35 
     | 
    
         
            +
                    visitor.stub(:visit).with(attribute_operator).and_return(visited)
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                    visit.should == visited
         
     | 
| 
      
 38 
     | 
    
         
            +
                  end
         
     | 
| 
      
 39 
     | 
    
         
            +
                end
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
                context 'with Metasploit::Model::Search::Operator::Attribute' do
         
     | 
| 
      
 42 
     | 
    
         
            +
                  let(:node) do
         
     | 
| 
      
 43 
     | 
    
         
            +
                    Metasploit::Model::Search::Operator::Attribute.new(
         
     | 
| 
      
 44 
     | 
    
         
            +
                        # needs to be a real column so look up on AREL table works
         
     | 
| 
      
 45 
     | 
    
         
            +
                        :attribute => :name,
         
     | 
| 
      
 46 
     | 
    
         
            +
                        # needs to be a real class so Class#arel_table works
         
     | 
| 
      
 47 
     | 
    
         
            +
                        :klass => Mdm::Host
         
     | 
| 
      
 48 
     | 
    
         
            +
                    )
         
     | 
| 
      
 49 
     | 
    
         
            +
                  end
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
                  it { should be_a Arel::Attributes::Attribute }
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
                  context 'name' do
         
     | 
| 
      
 54 
     | 
    
         
            +
                    subject(:name) do
         
     | 
| 
      
 55 
     | 
    
         
            +
                      visit.name
         
     | 
| 
      
 56 
     | 
    
         
            +
                    end
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
                    it 'should be Metasploit::Model::Search::Operator::Attribute#attribute' do
         
     | 
| 
      
 59 
     | 
    
         
            +
                      name.should == node.attribute
         
     | 
| 
      
 60 
     | 
    
         
            +
                    end
         
     | 
| 
      
 61 
     | 
    
         
            +
                  end
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
                  context 'relation' do
         
     | 
| 
      
 64 
     | 
    
         
            +
                    subject(:relation) do
         
     | 
| 
      
 65 
     | 
    
         
            +
                      visit.relation
         
     | 
| 
      
 66 
     | 
    
         
            +
                    end
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
                    it 'should be Class#arel_table for Metasploit::Model::Search::Operator::Attribute#klass' do
         
     | 
| 
      
 69 
     | 
    
         
            +
                      relation.should == node.klass.arel_table
         
     | 
| 
      
 70 
     | 
    
         
            +
                    end
         
     | 
| 
      
 71 
     | 
    
         
            +
                  end
         
     | 
| 
      
 72 
     | 
    
         
            +
                end
         
     | 
| 
      
 73 
     | 
    
         
            +
              end
         
     | 
| 
      
 74 
     | 
    
         
            +
            end
         
     |