metasploit-erd 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/.coveralls.yml +1 -0
- data/.gitignore +26 -0
- data/.rspec +3 -0
- data/.simplecov +42 -0
- data/.travis.yml +7 -0
- data/.yardopts +1 -0
- data/Gemfile +26 -0
- data/LICENSE +28 -0
- data/README.md +44 -0
- data/Rakefile +9 -0
- data/lib/metasploit/erd.rb +35 -0
- data/lib/metasploit/erd/cluster.rb +49 -0
- data/lib/metasploit/erd/clusterable.rb +39 -0
- data/lib/metasploit/erd/diagram.rb +89 -0
- data/lib/metasploit/erd/entity.rb +11 -0
- data/lib/metasploit/erd/entity/class.rb +69 -0
- data/lib/metasploit/erd/entity/namespace.rb +66 -0
- data/lib/metasploit/erd/relationship.rb +57 -0
- data/lib/metasploit/erd/version.rb +31 -0
- data/lib/tasks/yard.rake +32 -0
- data/metasploit-erd.gemspec +33 -0
- data/spec/metasploit/erd/cluster_spec.rb +158 -0
- data/spec/metasploit/erd/diagram_spec.rb +238 -0
- data/spec/metasploit/erd/entity/class_spec.rb +236 -0
- data/spec/metasploit/erd/entity/namespace_spec.rb +130 -0
- data/spec/metasploit/erd/relationship_spec.rb +246 -0
- data/spec/metasploit/erd/version_spec.rb +125 -0
- data/spec/metasploit/erd_spec.rb +15 -0
- data/spec/spec_helper.rb +26 -0
- data/spec/support/shared/contexts/active_record_base_connection.rb +12 -0
- data/spec/support/shared/contexts/active_record_base_descendants_cleaner.rb +11 -0
- data/spec/support/shared/examples/metasploit/erd/clusterable.rb +284 -0
- metadata +187 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
OWM3NzNkYTA5NTA2NmYxZGIwMDdkYTA5OTcxMTUwOGZlNDM0MTcxYw==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
ZmFmYjJjYWJkYzYyMDkwNWZhODNmNTQyOTFkNTk1NjMyODNmYmVhYQ==
|
7
|
+
SHA512:
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
ZWNmNWIyZjc0YTBkMDMzNWNkY2JmOTVkZGNiNWNlZTQzM2RkYmY3MDMxMTcx
|
10
|
+
MmFjNDZhNmVlNWQ2MjQzZDdkZWJmZDUxZWY2NWE2ZTQ4ZjcwNWNhMDA0MWNm
|
11
|
+
NmQ3MDBlNGIzNjBjZjY3NGZkOWEyNTAwNDkyZmUyZjUwMTNmNzc=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
NmNhZDFmOGE1ODI4MjhjZmMyYTFmMmQ5YjUzYzAzMjgzZWJjNzRhNzYwZGY3
|
14
|
+
OGFlZTMxZjI5YTA5NmYyMjUxYWFlZjEwYjYxNzAyNWQ1YjliNjE1YTM5ODI2
|
15
|
+
Yjg1NDE0MDg2NzJhOTUyZjU1MGQ1ZTI3ZDcxYzI2N2E4ZjM0ZTM=
|
data/.coveralls.yml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
service_name: travis-ci
|
data/.gitignore
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# bundler
|
2
|
+
.bundle
|
3
|
+
|
4
|
+
# Rubymine
|
5
|
+
.idea
|
6
|
+
|
7
|
+
# rvm files should not be checked in as multiple rubies are supported in the CI builds
|
8
|
+
.ruby-gemset
|
9
|
+
.ruby-version
|
10
|
+
|
11
|
+
# YARD
|
12
|
+
.yardoc
|
13
|
+
doc
|
14
|
+
|
15
|
+
# simplecov
|
16
|
+
coverage
|
17
|
+
|
18
|
+
# @see http://yehudakatz.com/2010/12/16/clarifying-the-roles-of-the-gemspec-and-gemfile/
|
19
|
+
Gemfile.lock
|
20
|
+
|
21
|
+
# built gems
|
22
|
+
pkg
|
23
|
+
*.gem
|
24
|
+
|
25
|
+
# compiled ruby from Rubinius
|
26
|
+
*.rbc
|
data/.rspec
ADDED
data/.simplecov
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
# RM_INFO is set when using Rubymine. In Rubymine, starting SimpleCov is
|
2
|
+
# controlled by running with coverage, so don't explicitly start coverage (and
|
3
|
+
# therefore generate a report) when in Rubymine. This _will_ generate a report
|
4
|
+
# whenever `rake spec` is run.
|
5
|
+
unless ENV['RM_INFO']
|
6
|
+
SimpleCov.start
|
7
|
+
end
|
8
|
+
|
9
|
+
SimpleCov.configure do
|
10
|
+
# ignore this file
|
11
|
+
add_filter '.simplecov'
|
12
|
+
|
13
|
+
# Rake tasks aren't tested with rspec
|
14
|
+
add_filter 'Rakefile'
|
15
|
+
add_filter 'lib/tasks'
|
16
|
+
|
17
|
+
#
|
18
|
+
# Changed Files in Git Group
|
19
|
+
# @see http://fredwu.me/post/35625566267/simplecov-test-coverage-for-changed-files-only
|
20
|
+
#
|
21
|
+
|
22
|
+
untracked = `git ls-files --exclude-standard --others`
|
23
|
+
unstaged = `git diff --name-only`
|
24
|
+
staged = `git diff --name-only --cached`
|
25
|
+
all = untracked + unstaged + staged
|
26
|
+
changed_filenames = all.split("\n")
|
27
|
+
|
28
|
+
add_group 'Changed' do |source_file|
|
29
|
+
changed_filenames.detect { |changed_filename|
|
30
|
+
source_file.filename.end_with?(changed_filename)
|
31
|
+
}
|
32
|
+
end
|
33
|
+
|
34
|
+
add_group 'Libraries', 'lib'
|
35
|
+
|
36
|
+
#
|
37
|
+
# Specs are reported on to ensure that all examples are being run and all
|
38
|
+
# lets, befores, afters, etc are being used.
|
39
|
+
#
|
40
|
+
|
41
|
+
add_group 'Specs', 'spec'
|
42
|
+
end
|
data/.travis.yml
ADDED
data/.yardopts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--markup markdown
|
data/Gemfile
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
# Specify your gem's dependencies in metasploit-erd.gemspec
|
4
|
+
gemspec
|
5
|
+
|
6
|
+
group :development do
|
7
|
+
# markdown formatting for yard
|
8
|
+
gem 'kramdown', platforms: :jruby
|
9
|
+
# markdown formatting for yard
|
10
|
+
gem 'redcarpet', platforms: :ruby
|
11
|
+
# documentation
|
12
|
+
# 0.8.7.4 has a bug where setters are not documented when @!attribute is used
|
13
|
+
gem 'yard', '< 0.8.7.4'
|
14
|
+
end
|
15
|
+
|
16
|
+
group :test do
|
17
|
+
# blank?
|
18
|
+
# restrict for compatibility with rest of metasploit ecosystem until it upgrades to Rails 4
|
19
|
+
gem 'activesupport', '>= 3.2', '< 4.0.0'
|
20
|
+
# Upload coverage reports to coveralls.io
|
21
|
+
gem 'coveralls', require: false
|
22
|
+
# code coverage of tests
|
23
|
+
gem 'simplecov', :require => false
|
24
|
+
# in-memory database for ActiveRecord association traversal
|
25
|
+
gem 'sqlite3'
|
26
|
+
end
|
data/LICENSE
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
Copyright (c) 2014 Rapid7, Inc.
|
2
|
+
|
3
|
+
License: BSD-3-clause
|
4
|
+
|
5
|
+
Redistribution and use in source and binary forms, with or without modification,
|
6
|
+
are permitted provided that the following conditions are met:
|
7
|
+
|
8
|
+
1. Redistributions of source code must retain the above copyright notice,
|
9
|
+
this list of conditions and the following disclaimer.
|
10
|
+
|
11
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
12
|
+
this list of conditions and the following disclaimer in the documentation
|
13
|
+
and/or other materials provided with the distribution.
|
14
|
+
|
15
|
+
3. Neither the name of Rapid7 LLC nor the names of its contributors
|
16
|
+
may be used to endorse or promote products derived from this software
|
17
|
+
without specific prior written permission.
|
18
|
+
|
19
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
20
|
+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
21
|
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
22
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
23
|
+
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
24
|
+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
25
|
+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
26
|
+
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
27
|
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
28
|
+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/README.md
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
# Metasploit::ERD [![Build Status](https://travis-ci.org/rapid7/metasploit-erd.svg?branch=feature/port)](https://travis-ci.org/rapid7/metasploit-erd)[![Code Climate](https://codeclimate.com/github/rapid7/metasploit-erd.png)](https://codeclimate.com/github/rapid7/metasploit-erd)[![Coverage Status](https://coveralls.io/repos/rapid7/metasploit-erd/badge.png)](https://coveralls.io/r/rapid7/metasploit-erd)[![Dependency Status](https://gemnasium.com/rapid7/metasploit-erd.png)](https://gemnasium.com/rapid7/metasploit-erd)[![Gem Version](https://badge.fury.io/rb/metasploit-erd.png)](http://badge.fury.io/rb/metasploit-erd)
|
2
|
+
|
3
|
+
Traces the `belongs_to` associations on `ActiveRecord::Base.descendants` to find the minimum cluster in which all
|
4
|
+
foreign keys are fulfilled in the Entity-Relationship Diagram.'
|
5
|
+
|
6
|
+
## Versioning
|
7
|
+
|
8
|
+
`Metasploit::ERD` is versioned using [semantic versioning 2.0](http://semver.org/spec/v2.0.0.html). Each branch
|
9
|
+
should set `Metasploit::ERD::Version::PRERELEASE` to the branch name, while master should have no `PRERELEASE`
|
10
|
+
and the `PRERELEASE` section of `Metasploit::ERD::VERSION` does not exist.
|
11
|
+
|
12
|
+
## Installation
|
13
|
+
|
14
|
+
### Gem
|
15
|
+
|
16
|
+
Add this line to your application's Gemfile:
|
17
|
+
|
18
|
+
gem 'metasploit-erd'
|
19
|
+
|
20
|
+
And then execute:
|
21
|
+
|
22
|
+
$ bundle
|
23
|
+
|
24
|
+
Or install it yourself as:
|
25
|
+
|
26
|
+
$ gem install metasploit-erd
|
27
|
+
|
28
|
+
### System tools
|
29
|
+
|
30
|
+
In order to generate the diagrams as PNGs, graphviz is used, which may have issues when use on OSX Mavericks. If you
|
31
|
+
get 'CoreTest performance note' messages when running 'rake yard', you should reinstall graphviz as follows:
|
32
|
+
`brew reinstall graphviz --with-bindings --with-freetype --with-librsvg --with-pangocairo`.
|
33
|
+
|
34
|
+
## Usage
|
35
|
+
|
36
|
+
TODO: Write usage instructions here
|
37
|
+
|
38
|
+
## Contributing
|
39
|
+
|
40
|
+
1. Fork it ( http://github.com/<my-github-username>/metasploit-erd/fork )
|
41
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
42
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
43
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
44
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
#
|
2
|
+
# Standard Library
|
3
|
+
#
|
4
|
+
|
5
|
+
require 'set'
|
6
|
+
|
7
|
+
#
|
8
|
+
# Gems
|
9
|
+
#
|
10
|
+
|
11
|
+
require 'active_record'
|
12
|
+
require 'active_support/dependencies/autoload'
|
13
|
+
|
14
|
+
#
|
15
|
+
# Project
|
16
|
+
#
|
17
|
+
|
18
|
+
require "metasploit/erd/version"
|
19
|
+
|
20
|
+
# Shared namespace for metasploit gems; used in {https://github.com/rapid7/metasploit-concern metasploit-concern},
|
21
|
+
# {https://github.com/rapid7/metasploit-erd metasploit-erd},
|
22
|
+
# {https://github.com/rapid7/metasploit-framework metasploit-framework}, and
|
23
|
+
# {https://github.com/rapid7/metasploit-model metasploit-model}
|
24
|
+
module Metasploit
|
25
|
+
# The namespace for this gem.
|
26
|
+
module ERD
|
27
|
+
extend ActiveSupport::Autoload
|
28
|
+
|
29
|
+
autoload :Cluster
|
30
|
+
autoload :Clusterable
|
31
|
+
autoload :Diagram
|
32
|
+
autoload :Entity
|
33
|
+
autoload :Relationship
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# A cluster of `Class<ActiveRecord::Base>` that are connected by `belongs_to` associations so that all foreign keys are
|
2
|
+
# paired with their appropriate primary keys.
|
3
|
+
class Metasploit::ERD::Cluster
|
4
|
+
#
|
5
|
+
# Instance Methods
|
6
|
+
#
|
7
|
+
|
8
|
+
# @param roots [Array<Class<ActiveRecord::Base>>] starting `ActiveRecord::Base` subclasses to seed {#class_set}.
|
9
|
+
def initialize(*roots)
|
10
|
+
class_queue.concat(roots)
|
11
|
+
end
|
12
|
+
|
13
|
+
# Clases that are reachable through `belongs_to` associations on classes passed as `roots` to {#initialize}.
|
14
|
+
#
|
15
|
+
# @return [Set<Class<ActiveRecord::Base>>]
|
16
|
+
def class_set
|
17
|
+
until class_queue.empty?
|
18
|
+
klass = class_queue.pop
|
19
|
+
# add immediately to visited set in case there are recursive associations
|
20
|
+
visited_class_set.add klass
|
21
|
+
|
22
|
+
class_entity = Metasploit::ERD::Entity::Class.new(klass)
|
23
|
+
|
24
|
+
class_entity.class_set.each do |klass|
|
25
|
+
unless visited_class_set.include? klass
|
26
|
+
class_queue << klass
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
superclass = klass.superclass
|
31
|
+
|
32
|
+
unless superclass == ActiveRecord::Base || visited_class_set.include?(superclass)
|
33
|
+
class_queue << superclass
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
visited_class_set
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def class_queue
|
43
|
+
@class_queue ||= []
|
44
|
+
end
|
45
|
+
|
46
|
+
def visited_class_set
|
47
|
+
@visited_class_set ||= Set.new
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'rails_erd/domain'
|
2
|
+
|
3
|
+
# Adds {#domain} and {#diagram} to any class that responds to `#cluster`.
|
4
|
+
module Metasploit::ERD::Clusterable
|
5
|
+
# Diagram using {#domain}.
|
6
|
+
#
|
7
|
+
# @param options (see Metasploit::ERD::Diagram#initialize)
|
8
|
+
# @option options (see Metasploit::ERD::Diagram#initialize)
|
9
|
+
# @option options [String] :basename The basename to use for the `:filename` option. Only use only if not `nil`.
|
10
|
+
# @option options [String] :diretory (Dir.pwd) The directory to use for the `:filename` options. Only used if
|
11
|
+
# `:basename` is not `nil`.
|
12
|
+
# @return [Metasploit::ERD:Diagram]
|
13
|
+
def diagram(options={})
|
14
|
+
merged_options = options.except(:basename, :directory)
|
15
|
+
basename = options[:basename]
|
16
|
+
|
17
|
+
if basename
|
18
|
+
directory = options[:directory]
|
19
|
+
# separate line so coverage can show this case is tested
|
20
|
+
directory ||= Dir.pwd
|
21
|
+
|
22
|
+
merged_options[:filename] = File.join(directory, basename)
|
23
|
+
end
|
24
|
+
|
25
|
+
Metasploit::ERD::Diagram.new(domain, merged_options)
|
26
|
+
end
|
27
|
+
|
28
|
+
# Domain restricted to `#cluster` {Metasploit::ERD::Cluster#class_set}
|
29
|
+
#
|
30
|
+
# @return [RailsERD::Domain]
|
31
|
+
def domain
|
32
|
+
RailsERD::Domain.new(
|
33
|
+
cluster.class_set,
|
34
|
+
# don't warn about missing entities in domain since only belongs_to associations are traced in the cluster and
|
35
|
+
# not has_many associations.
|
36
|
+
warn: false
|
37
|
+
)
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'rails_erd/diagram/graphviz'
|
2
|
+
|
3
|
+
# A diagram specialized with default options that work well with {Metasploit::ERD::Clusterable#domain}.
|
4
|
+
class Metasploit::ERD::Diagram < RailsERD::Diagram::Graphviz
|
5
|
+
#
|
6
|
+
# CONSTANTS
|
7
|
+
#
|
8
|
+
|
9
|
+
# Enable all attributes
|
10
|
+
ATTRIBUTES = [
|
11
|
+
:content,
|
12
|
+
:foreign_keys,
|
13
|
+
:primary_keys,
|
14
|
+
:timestamps
|
15
|
+
]
|
16
|
+
|
17
|
+
# File type that work for embedding in web pages and is lossless.
|
18
|
+
FILETYPE = :png
|
19
|
+
|
20
|
+
# Only show direct relationships because anything indirect can be found by tracing the direct arrows and only showing
|
21
|
+
# direct relationships cuts down on cluster
|
22
|
+
INDIRECT = false
|
23
|
+
|
24
|
+
# Show inheritance for Single Table Inheritance
|
25
|
+
INHERITANCE = true
|
26
|
+
|
27
|
+
# Use crowsfoot notation since its what metasploit uses for manually drawn and graffle diagrams.
|
28
|
+
NOTATION = :crowsfoot
|
29
|
+
|
30
|
+
# Show polymorphic association connections as they are traced by
|
31
|
+
# {Metasploit::ERD::Relationship#polymorphic_class_set}.
|
32
|
+
POLYMORPHISM = true
|
33
|
+
|
34
|
+
# Default options for {#initialize}
|
35
|
+
DEFAULT_OPTIONS = {
|
36
|
+
attributes: ATTRIBUTES,
|
37
|
+
filetype: FILETYPE,
|
38
|
+
indirect: INDIRECT,
|
39
|
+
inheritance: INHERITANCE,
|
40
|
+
notation: NOTATION,
|
41
|
+
polymorphism: POLYMORPHISM
|
42
|
+
}
|
43
|
+
|
44
|
+
#
|
45
|
+
# Callbacks
|
46
|
+
#
|
47
|
+
|
48
|
+
# Callbacks are not inherited normally, so this emulates inheriting
|
49
|
+
callbacks.merge!(superclass.send(:callbacks))
|
50
|
+
|
51
|
+
# super() for save
|
52
|
+
supersave = callbacks[:save]
|
53
|
+
|
54
|
+
# Automatically create parent directory if it does not exist.
|
55
|
+
save {
|
56
|
+
parent = Pathname.new(filename).parent
|
57
|
+
|
58
|
+
unless parent.directory?
|
59
|
+
parent.mkpath
|
60
|
+
end
|
61
|
+
|
62
|
+
instance_eval &supersave
|
63
|
+
}
|
64
|
+
|
65
|
+
#
|
66
|
+
# Instance Methods
|
67
|
+
#
|
68
|
+
|
69
|
+
# @param domain [RailsERD::Domain] domain to diagram
|
70
|
+
# @param options [Hash{Symbol => Object}] options controlling what to include from domain and how to render diagram.
|
71
|
+
# Defaults to {Metasploit::ERD::Diagram::DEFAULT_OPTIONS}.
|
72
|
+
# @option options [Array<Symbol>] :attributes (ATTRIBUTES) attributes of each entity (table) to include in the
|
73
|
+
# diagram.
|
74
|
+
# @option options [String, Symbol] :filetype (FILETYPE) the file type of the generated diagram. Supported formats
|
75
|
+
# depend on formats supported by graphviz installation.
|
76
|
+
# @option options [Boolean] :indirect (INDIRECT) Whether to include indirect (`has_many through:`) relationships.
|
77
|
+
# @option options [Boolean] :inheritance (INHERITANCE) Whether to include Single Table Inheritance (STI) subclass
|
78
|
+
# entities.
|
79
|
+
# @option options [Symbol] :notation (NOTATION) The cardinality notation to be used. Refer to RailsERD
|
80
|
+
# documentation for availble notations.
|
81
|
+
# @option options [:horizontal, :vertical] :orientation (:horizontal) The directory of the hierarchy of entities.
|
82
|
+
# @option options [Boolean] :polymorphism (POLYMORPHISM) Whether to include abstract or polymorphic pseudo-entities.
|
83
|
+
# @option options [String] :title Title for diagram.
|
84
|
+
def initialize(domain, options={})
|
85
|
+
super_options = DEFAULT_OPTIONS.merge(options)
|
86
|
+
|
87
|
+
super(domain, super_options)
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'active_support/dependencies/autoload'
|
2
|
+
|
3
|
+
# Namespace for classes that function as Entities in Entity-Relationship diagrams, such as
|
4
|
+
# {Metasploit::ERD::Entity::Class `ActiveRecord::Base` subclasses} or
|
5
|
+
# {Metasploit::ERD::Entity::Namespace namespace `Module`s}.
|
6
|
+
module Metasploit::ERD::Entity
|
7
|
+
extend ActiveSupport::Autoload
|
8
|
+
|
9
|
+
autoload :Class
|
10
|
+
autoload :Namespace
|
11
|
+
end
|