stratagem 0.1.8 → 0.1.9
Sign up to get free protection for your applications and to get access to all the features.
- data/Manifest +16 -18
- data/Rakefile +3 -3
- data/bin/stratagem +54 -6
- data/generators/stratagem/stratagem_generator.rb +26 -0
- data/lib/generators/stratagem/install/USAGE +0 -0
- data/lib/generators/stratagem/install/install_base.rb +35 -0
- data/lib/generators/stratagem/install/install_generator.rb +24 -0
- data/lib/stratagem.rb +87 -57
- data/lib/stratagem/authentication.rb +2 -2
- data/lib/stratagem/auto_mock/aquifer.rb +6 -1
- data/lib/stratagem/auto_mock/factory.rb +2 -2
- data/lib/stratagem/client.rb +1 -1
- data/lib/stratagem/crawler.rb +2 -0
- data/lib/stratagem/crawler/authentication.rb +10 -9
- data/lib/stratagem/crawler/parameter_resolver.rb +83 -0
- data/lib/stratagem/crawler/route_invoker.rb +187 -0
- data/lib/stratagem/crawler/session.rb +23 -251
- data/lib/stratagem/crawler/site_model.rb +18 -16
- data/lib/stratagem/framework_extensions.rb +12 -1
- data/lib/stratagem/framework_extensions/method_invocation.rb +50 -0
- data/lib/stratagem/framework_extensions/models/adapters/active_model/detect.rb +1 -1
- data/lib/stratagem/framework_extensions/models/adapters/active_model/extensions.rb +20 -11
- data/lib/stratagem/framework_extensions/models/adapters/active_model/metadata.rb +7 -3
- data/lib/stratagem/framework_extensions/models/adapters/active_model/tracing.rb +11 -9
- data/lib/stratagem/framework_extensions/models/adapters/friendly_id/detect.rb +12 -0
- data/lib/stratagem/framework_extensions/models/adapters/friendly_id/extensions.rb +0 -0
- data/lib/stratagem/framework_extensions/models/adapters/friendly_id/metadata.rb +21 -0
- data/lib/stratagem/framework_extensions/models/adapters/friendly_id/tracing.rb +4 -0
- data/lib/stratagem/framework_extensions/models/annotations.rb +1 -24
- data/lib/stratagem/framework_extensions/models/tracing.rb +9 -3
- data/lib/stratagem/framework_extensions/rails.rb +0 -6
- data/lib/stratagem/framework_extensions/{controllers → rails2}/action_controller.rb +0 -0
- data/lib/stratagem/framework_extensions/{controllers → rails2}/action_mailer.rb +0 -0
- data/lib/stratagem/framework_extensions/rails3/parameters.rb +14 -0
- data/lib/stratagem/interface/browser.rb +3 -1
- data/lib/stratagem/model/application.rb +6 -6
- data/lib/stratagem/model/components/controller.rb +17 -63
- data/lib/stratagem/model/components/model.rb +33 -33
- data/lib/stratagem/model/components/reference.rb +8 -4
- data/lib/stratagem/model/components/route.rb +40 -14
- data/lib/stratagem/model/components/view.rb +1 -1
- data/lib/stratagem/model_builder.rb +71 -42
- data/lib/stratagem/site_crawler.rb +1 -1
- data/lib/stratagem/snapshot.rb +0 -1
- data/stratagem.gemspec +10 -7
- data/templates/install/environments/stratagem.rb.erb +16 -0
- data/templates/install/tasks/stratagem.rake +18 -0
- metadata +57 -40
- data/lib/stratagem/framework_extensions/controllers.rb +0 -5
- data/lib/stratagem/scan/checks/filter_parameter_logging.rb +0 -6
- data/lib/stratagem/scan/checks/mongo_mapper/base.rb +0 -19
- data/lib/stratagem/scan/checks/mongo_mapper/foreign_keys_exposed.rb +0 -32
- data/lib/stratagem/scan/checks/routes.rb +0 -16
- data/lib/tasks/_old_stratagem.rake +0 -99
- data/spec/model/component_spec.rb +0 -43
- data/spec/model/components/view_spec.rb +0 -43
- data/spec/model/test_spec.rb +0 -10
- data/spec/samples/404.html.erb +0 -30
- data/spec/samples/_form.html.erb +0 -8
- data/spec/samples/index.html.erb +0 -77
- data/spec/samples/sample_model.rb +0 -5
- data/spec/samples/signup.html.erb +0 -14
- data/spec/scan/checks/email_address_spec.rb +0 -24
- data/spec/scan/checks/error_pages_spec.rb +0 -22
@@ -29,8 +29,8 @@ module Stratagem::Crawler
|
|
29
29
|
self.edges << Edge.new(from,to,type)
|
30
30
|
end
|
31
31
|
|
32
|
-
def add(route, response, invocations=[], model_changes={}, &block)
|
33
|
-
page = Page.new(self, response, invocations, model_changes, &block)
|
32
|
+
def add(route, request, response, invocations=[], model_changes={}, &block)
|
33
|
+
page = Page.new(self, request, response, invocations, model_changes, &block)
|
34
34
|
self.pages << page
|
35
35
|
page
|
36
36
|
end
|
@@ -59,7 +59,7 @@ module Stratagem::Crawler
|
|
59
59
|
{
|
60
60
|
:from => from.object_id,
|
61
61
|
:to => to.object_id,
|
62
|
-
:
|
62
|
+
:relation_type => type
|
63
63
|
}
|
64
64
|
end
|
65
65
|
end
|
@@ -75,36 +75,38 @@ module Stratagem::Crawler
|
|
75
75
|
attr_accessor :redirected_to
|
76
76
|
attr_accessor :document
|
77
77
|
|
78
|
-
def initialize(site_model, response, invocations, model_changes, &block)
|
78
|
+
def initialize(site_model, request, response, invocations, model_changes, &block)
|
79
79
|
@site_model = site_model
|
80
80
|
@invocations = invocations
|
81
81
|
@model_changes = model_changes
|
82
|
-
init(response, &block)
|
82
|
+
init(request, response, &block)
|
83
83
|
end
|
84
84
|
|
85
85
|
def route
|
86
|
-
Stratagem::Model::Application.instance.routes.recognize(self)
|
86
|
+
@route ||= Stratagem::Model::Application.instance.routes.recognize(self)
|
87
87
|
end
|
88
88
|
|
89
89
|
def export
|
90
|
-
{
|
90
|
+
h = {
|
91
91
|
:external_id => self.object_id,
|
92
92
|
:url => url,
|
93
93
|
:path => path,
|
94
|
-
:
|
94
|
+
:request_method => method,
|
95
95
|
:redirected_to_page_external_id => redirected_to ? redirected_to.object_id : nil,
|
96
|
-
:route_external_id => route.object_id,
|
96
|
+
:route_external_id => route ? route.object_id : nil,
|
97
97
|
:references => @invocations.map {|i| i.to_reference.export },
|
98
98
|
:model_changes => Hash[@model_changes.map {|model,changes| [model.object_id, changes] }].to_json,
|
99
|
-
:parameters =>
|
99
|
+
:parameters => @request.parameters.to_json
|
100
100
|
}
|
101
|
+
h
|
101
102
|
end
|
102
103
|
|
103
|
-
def init(response, &block)
|
104
|
+
def init(request, response, &block)
|
105
|
+
@request = request.clone
|
104
106
|
@response = response.clone
|
105
|
-
@url =
|
106
|
-
@path =
|
107
|
-
@method =
|
107
|
+
@url = request.url
|
108
|
+
@path = request.path
|
109
|
+
@method = request.method
|
108
110
|
@document = Nokogiri::HTML(response.body)
|
109
111
|
self.redirected_to = block.call(response.redirect_url) if response.redirect?
|
110
112
|
end
|
@@ -112,8 +114,8 @@ module Stratagem::Crawler
|
|
112
114
|
def reload(&block)
|
113
115
|
# TODO - should support all the verbs and params, but
|
114
116
|
# hack together for now to reload the authenticity token
|
115
|
-
response = yield url
|
116
|
-
init(response) {|redirected_to| }
|
117
|
+
request,response = yield url
|
118
|
+
init(request, response) {|redirected_to| }
|
117
119
|
end
|
118
120
|
|
119
121
|
def redirected?
|
@@ -1,6 +1,17 @@
|
|
1
1
|
module Stratagem::ApplicationExtensions; end
|
2
2
|
|
3
3
|
require 'stratagem/framework_extensions/rails'
|
4
|
-
require 'stratagem/framework_extensions/
|
4
|
+
require 'stratagem/framework_extensions/method_invocation'
|
5
5
|
require 'stratagem/framework_extensions/models'
|
6
6
|
|
7
|
+
if (Stratagem.rails_3?)
|
8
|
+
require 'stratagem/framework_extensions/rails3/parameters'
|
9
|
+
elsif (Stratagem.rails_2?)
|
10
|
+
require 'stratagem/framework_extensions/rails2/action_controller'
|
11
|
+
require 'stratagem/framework_extensions/rails2/action_mailer'
|
12
|
+
else
|
13
|
+
raise "Unsupported Rails version #{Stratagem.rails_version}"
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module Stratagem::ApplicationExtensions
|
2
|
+
class MethodInvocation
|
3
|
+
attr_accessor :method, :controller_path, :controller_action, :line_number, :model_instance, :model_class, :stack_trace, :args, :type
|
4
|
+
|
5
|
+
EQUALITY_ATTRS = [:method, :controller_path, :controller_action, :line_number, :model_class]
|
6
|
+
|
7
|
+
# TODO - refactor, ugly constructor is a result of quick port from Struct
|
8
|
+
def initialize(*args)
|
9
|
+
arg_keys = [:method, :controller_path, :controller_action, :line_number, :model_instance, :model_class, :stack_trace, :args, :type]
|
10
|
+
args.each_with_index do |val,i|
|
11
|
+
self.send("#{arg_keys[i].to_s}=", val)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def <=>(other)
|
16
|
+
e = self.==(other)
|
17
|
+
e ? 0 : 1
|
18
|
+
end
|
19
|
+
|
20
|
+
def ==(other)
|
21
|
+
eql?(other)
|
22
|
+
end
|
23
|
+
|
24
|
+
# override so that uniq works properly
|
25
|
+
def eql?(other)
|
26
|
+
EQUALITY_ATTRS.find {|key|
|
27
|
+
(self.send(key) != other.send(key))
|
28
|
+
}.nil?
|
29
|
+
end
|
30
|
+
|
31
|
+
def to_reference
|
32
|
+
app = Stratagem::Model::Application.instance
|
33
|
+
model = model_class ? app.models.find {|model| model.klass == model_class } : nil
|
34
|
+
controller = controller_path ? app.controllers.find {|controller| controller.path == controller_path } : nil
|
35
|
+
Stratagem::Model::Component::Reference.new(
|
36
|
+
:from_component => controller,
|
37
|
+
:to_component => model,
|
38
|
+
:function => controller_action,
|
39
|
+
:request_method => method,
|
40
|
+
:line_number => line_number,
|
41
|
+
:reference_type => type,
|
42
|
+
:stack_trace => stack_trace
|
43
|
+
)
|
44
|
+
end
|
45
|
+
|
46
|
+
def print
|
47
|
+
puts "#{controller_path}.#{controller_action}:#{line_number} -> #{model_class.name}.#{method}"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
module Stratagem::ApplicationExtensions::Models::Adapters::
|
1
|
+
module Stratagem::ApplicationExtensions::Models::Adapters::ActiveRecord
|
2
2
|
class Detect < Stratagem::ApplicationExtensions::Models::Detect
|
3
3
|
def self.supports?(model)
|
4
4
|
model.ancestors.include?(ActiveRecord::Base)
|
@@ -17,18 +17,27 @@ class ActiveRecord::Base
|
|
17
17
|
|
18
18
|
end
|
19
19
|
|
20
|
-
|
20
|
+
class ActiveRecord::Base #Validations::ClassMethods
|
21
21
|
@@removed_validators = []
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
22
|
+
#
|
23
|
+
# instance_methods.each do |m|
|
24
|
+
# if (m =~ /^validates_/) && (m !~ /validates_each/)
|
25
|
+
# alias_method "old_#{m}", m
|
26
|
+
# undef_method m
|
27
|
+
# puts "removing validator #{m}"
|
28
|
+
# @@removed_validators << m.to_sym
|
29
|
+
#
|
30
|
+
#
|
31
|
+
# new_method = %Q{
|
32
|
+
# def #{m.to_sym}(*args)
|
33
|
+
# stratagem.validator_called(method, args)
|
34
|
+
# puts "calling validator \#\{method.to_s\} with \#\{args.inspect\}"
|
35
|
+
# send("old_"+method.to_s, *args, &block)
|
36
|
+
# end}
|
37
|
+
# instance_eval new_method
|
38
|
+
# end
|
39
|
+
# end
|
40
|
+
#
|
32
41
|
def removed_validators
|
33
42
|
@@removed_validators
|
34
43
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
module Stratagem::ApplicationExtensions::Models::Adapters::
|
1
|
+
module Stratagem::ApplicationExtensions::Models::Adapters::ActiveRecord
|
2
2
|
|
3
3
|
# prefix method names with to avoid collision
|
4
4
|
class Metadata
|
@@ -13,8 +13,12 @@ module Stratagem::ApplicationExtensions::Models::Adapters::ActiveModel
|
|
13
13
|
def relations(relation_type=nil) # :belongs_to, :has_many
|
14
14
|
@relations ||= {}
|
15
15
|
@relations[relation_type || :all] ||= model.reflect_on_all_associations(relation_type).map {|a|
|
16
|
-
|
17
|
-
|
16
|
+
begin
|
17
|
+
Stratagem::ApplicationExtensions::Models::Metadata::StratagemAssociation.new(a.name.to_sym, a.association_foreign_key.to_sym, a.klass, a.macro, a.options)
|
18
|
+
rescue
|
19
|
+
puts "ERROR: #{$!.message}"
|
20
|
+
end
|
21
|
+
}.compact
|
18
22
|
end
|
19
23
|
|
20
24
|
def unaccessible_attributes
|
@@ -1,4 +1,4 @@
|
|
1
|
-
module Stratagem::ApplicationExtensions::Models::Adapters::
|
1
|
+
module Stratagem::ApplicationExtensions::Models::Adapters::ActiveRecord
|
2
2
|
module Tracing
|
3
3
|
def self.included(model)
|
4
4
|
model.class_eval do
|
@@ -22,14 +22,17 @@ module Stratagem::ApplicationExtensions::Models::Adapters::ActiveModel
|
|
22
22
|
# enhance method missing
|
23
23
|
class << self
|
24
24
|
def method_missing(method, *args, &block)
|
25
|
-
|
25
|
+
method = method.to_sym
|
26
|
+
if (self.removed_methods.include?(method))
|
26
27
|
# puts "read invocation: #{self.name} -> #{method} -> #{args.inspect}"
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
stratagem.validator_called(method, args)
|
31
|
-
puts "calling validator #{method.to_s} with #{args.inspect}"
|
28
|
+
if (@@removed_finder_methods.include?(method))# && ![:finder_needs_type_condition?].include?(method))
|
29
|
+
stratagem.read_invocation(method, args)
|
30
|
+
end
|
32
31
|
send("old_"+method.to_s, *args, &block)
|
32
|
+
# elsif (self.removed_validators.include?(method.to_sym))
|
33
|
+
# stratagem.validator_called(method, args)
|
34
|
+
# puts "calling validator #{method.to_s} with #{args.inspect}"
|
35
|
+
# send("old_"+method.to_s, *args, &block)
|
33
36
|
else
|
34
37
|
old_method_missing(method, *args, &block)
|
35
38
|
end
|
@@ -40,14 +43,13 @@ module Stratagem::ApplicationExtensions::Models::Adapters::ActiveModel
|
|
40
43
|
|
41
44
|
def create_or_update(*args)
|
42
45
|
alternate_model = nil
|
43
|
-
path,action,line,trace,index = stratagem.controller_trace(
|
46
|
+
path,action,line,trace,index = stratagem.controller_trace(/\/active_record\/transactions\.rb/)
|
44
47
|
if (index)
|
45
48
|
model_path,model_action,model_line = find_model_path(trace,index)
|
46
49
|
if (model_path)
|
47
50
|
puts "WRITE INVOCATION - USING: #{model_path},#{model_action},#{model_line}"
|
48
51
|
alternate_model = Stratagem::Model::Application.instance.models.find {|m| m.path == model_path }.klass
|
49
52
|
action = model_action
|
50
|
-
puts alternate_model
|
51
53
|
end
|
52
54
|
end
|
53
55
|
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module Stratagem::ApplicationExtensions::Models::Adapters::FriendlyId
|
2
|
+
class Detect < Stratagem::ApplicationExtensions::Models::Detect
|
3
|
+
def self.supports?(model)
|
4
|
+
begin
|
5
|
+
model.ancestors.include?(FriendlyId::ActiveRecordAdapter::SluggedModel) ||
|
6
|
+
model.ancestors.include?(FriendlyId::ActiveRecordAdapter::SimpleModel)
|
7
|
+
rescue
|
8
|
+
false
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
File without changes
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Stratagem::ApplicationExtensions::Models::Adapters::FriendlyId
|
2
|
+
|
3
|
+
# prefix method names with to avoid collision
|
4
|
+
class Metadata
|
5
|
+
def initialize(model)
|
6
|
+
@model = model
|
7
|
+
end
|
8
|
+
|
9
|
+
def exclude_attributes_for_mocking
|
10
|
+
# open id
|
11
|
+
attrs = @model.stratagem.attribute_names.select {|a|
|
12
|
+
(a =~ /friendly_id/)
|
13
|
+
}
|
14
|
+
attrs << :friendly_id_config
|
15
|
+
attrs << :cached_slug
|
16
|
+
|
17
|
+
attrs.uniq
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
@@ -1,30 +1,7 @@
|
|
1
1
|
# Defines the stratagem namespace attached to the model
|
2
2
|
module Stratagem::ApplicationExtensions::Models
|
3
|
-
MethodInvocation = Struct.new(:method, :controller_path, :controller_action, :line_number, :model_instance, :model_class, :stack_trace, :args, :type)
|
4
3
|
ValidatorDefinition = Struct.new(:validation, :field, :args, :model_class)
|
5
4
|
|
6
|
-
# Ability to convert a MethodInvocation object to a Reference object. Sort of a hack.
|
7
|
-
module MethodInvocationToReference
|
8
|
-
def to_reference
|
9
|
-
app = Stratagem::Model::Application.instance
|
10
|
-
model = model_class ? app.models.find {|model| model.klass == model_class } : nil
|
11
|
-
controller = controller_path ? app.controllers.find {|controller| controller.path == controller_path } : nil
|
12
|
-
Stratagem::Model::Component::Reference.new(
|
13
|
-
:from_component => controller,
|
14
|
-
:to_component => model,
|
15
|
-
:function => controller_action,
|
16
|
-
:method => method,
|
17
|
-
:line_number => line_number,
|
18
|
-
:reference_type => type,
|
19
|
-
:stack_trace => stack_trace
|
20
|
-
)
|
21
|
-
end
|
22
|
-
end
|
23
|
-
MethodInvocation.class_eval do
|
24
|
-
include MethodInvocationToReference
|
25
|
-
end
|
26
|
-
|
27
|
-
|
28
5
|
class InstanceAnnotations
|
29
6
|
include Mocking
|
30
7
|
|
@@ -48,7 +25,7 @@ module Stratagem::ApplicationExtensions::Models
|
|
48
25
|
class << self
|
49
26
|
def configure(model)
|
50
27
|
puts "configuring #{model.name}"
|
51
|
-
|
28
|
+
|
52
29
|
# add the stratagem namespace
|
53
30
|
model.class_eval do
|
54
31
|
def self.stratagem
|
@@ -38,14 +38,20 @@ module Stratagem::ApplicationExtensions::Models
|
|
38
38
|
|
39
39
|
def read_invocation(method, *args)
|
40
40
|
# ensure that the read did not stem from a write operation
|
41
|
-
|
42
|
-
|
41
|
+
|
42
|
+
# the first line in the stack trace will be StrataGem instrumentation
|
43
|
+
# if the second line is active record then the invocation was called from another invocation
|
44
|
+
# and should be ignored
|
45
|
+
unless (caller()[1].include?('active_record/base.rb'))
|
46
|
+
path,action,line,trace,index = controller_trace(/active_record\/base\.rb/)
|
47
|
+
invocation(method, args, read_invocations, :read) unless (action =~ /create/) || (action =~ /update/) || (action =~ /save/)
|
48
|
+
end
|
43
49
|
end
|
44
50
|
|
45
51
|
def invocation(method, args, enumeration, type, object=nil, alternate_model=nil)
|
46
52
|
path,action,line,trace,index = controller_trace
|
47
53
|
args = args.first if args && (args.size == 1) && (args.first.kind_of?(Array))
|
48
|
-
add_invocation enumeration, MethodInvocation.new(method, path, action, line, object, alternate_model || model, caller, args, type) if (path)
|
54
|
+
add_invocation enumeration, Stratagem::ApplicationExtensions::MethodInvocation.new(method, path, action, line, object, alternate_model || model, caller, args, type) if (path)
|
49
55
|
end
|
50
56
|
|
51
57
|
def controller_trace(regex = /_controller\.rb/)
|
File without changes
|
File without changes
|
@@ -34,6 +34,8 @@ module Stratagem::Model
|
|
34
34
|
references = @controllers.map {|c| c.references }.flatten.map {|r| r.export }.uniq
|
35
35
|
h = {
|
36
36
|
:rails_version => rails_version,
|
37
|
+
:rails_environment => Rails.env,
|
38
|
+
:rails_root => Rails.root,
|
37
39
|
:models => @models.export,
|
38
40
|
:controllers => @controllers.export,
|
39
41
|
:routes => @routes.export,
|
@@ -43,12 +45,12 @@ module Stratagem::Model
|
|
43
45
|
:site_model => crawler ? crawler.export : nil,
|
44
46
|
:references => references
|
45
47
|
}
|
46
|
-
|
48
|
+
puts h.to_json
|
47
49
|
h
|
48
50
|
end
|
49
51
|
|
50
52
|
def rails_version
|
51
|
-
|
53
|
+
Stratagem.rails_version
|
52
54
|
end
|
53
55
|
end
|
54
56
|
|
@@ -134,7 +136,7 @@ module Stratagem::Model
|
|
134
136
|
end
|
135
137
|
|
136
138
|
class RouteContainer < ComponentContainer
|
137
|
-
def recognize(page, method=
|
139
|
+
def recognize(page, method = :get)
|
138
140
|
path = nil
|
139
141
|
if (page.kind_of?(Stratagem::Crawler::Page))
|
140
142
|
method = page.method
|
@@ -142,9 +144,7 @@ module Stratagem::Model
|
|
142
144
|
else
|
143
145
|
path = page
|
144
146
|
end
|
145
|
-
|
146
|
-
route = ActionController::Routing::Routes.routes.find {|r| r.recognize(path, {:method => method}) }
|
147
|
-
self.find {|r| r.route == route }
|
147
|
+
self.find {|r| r.responds_to?(path, method) }
|
148
148
|
end
|
149
149
|
end
|
150
150
|
|