stratagem 0.2.0 → 0.2.2
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +29 -0
- data/Manifest +40 -38
- data/Rakefile +3 -3
- data/lib/stratagem.rb +22 -7
- data/lib/stratagem/authentication.rb +2 -1
- data/lib/stratagem/auto_mock/aquifer.rb +88 -15
- data/lib/stratagem/auto_mock/factory.rb +19 -30
- data/lib/stratagem/auto_mock/value_generator.rb +3 -1
- data/lib/stratagem/client.rb +3 -2
- data/lib/stratagem/crawler/authentication.rb +10 -3
- data/lib/stratagem/crawler/form.rb +2 -2
- data/lib/stratagem/crawler/html_utils.rb +12 -1
- data/lib/stratagem/crawler/parameter_resolver.rb +18 -4
- data/lib/stratagem/crawler/route_invoker.rb +58 -16
- data/lib/stratagem/crawler/session.rb +13 -5
- data/lib/stratagem/crawler/site_model.rb +20 -8
- data/lib/stratagem/extensions/object.rb +2 -2
- data/lib/stratagem/extensions/string.rb +2 -2
- data/lib/stratagem/instrumentation.rb +18 -0
- data/lib/stratagem/{framework_extensions → instrumentation}/method_invocation.rb +1 -1
- data/lib/stratagem/instrumentation/models.rb +25 -0
- data/lib/stratagem/instrumentation/models/annotations.rb +114 -0
- data/lib/stratagem/instrumentation/models/association.rb +40 -0
- data/lib/stratagem/instrumentation/models/authentication.rb +7 -0
- data/lib/stratagem/{framework_extensions/models/adapters → instrumentation/models/authentication}/authlogic/detect.rb +2 -2
- data/lib/stratagem/instrumentation/models/authentication/authlogic/instrumentation.rb +13 -0
- data/lib/stratagem/{framework_extensions/models/adapters → instrumentation/models/authentication}/authlogic/metadata.rb +1 -3
- data/lib/stratagem/instrumentation/models/authentication/devise/detect.rb +11 -0
- data/lib/stratagem/instrumentation/models/authentication/devise/instrumentation.rb +18 -0
- data/lib/stratagem/{framework_extensions/models/adapters → instrumentation/models/authentication}/devise/metadata.rb +7 -3
- data/lib/stratagem/{framework_extensions/models/adapters/util/authentication_metadata.rb → instrumentation/models/authentication/metadata.rb} +2 -2
- data/lib/stratagem/{framework_extensions/models/adapters → instrumentation/models/authentication}/restful_authentication/detect.rb +2 -4
- data/lib/stratagem/{framework_extensions/models/adapters/restful_authentication/extensions.rb → instrumentation/models/authentication/restful_authentication/instrumentation.rb} +1 -1
- data/lib/stratagem/{framework_extensions/models/adapters → instrumentation/models/authentication}/restful_authentication/metadata.rb +2 -2
- data/lib/stratagem/{framework_extensions → instrumentation}/models/detect.rb +1 -1
- data/lib/stratagem/{framework_extensions → instrumentation}/models/metadata.rb +6 -4
- data/lib/stratagem/{framework_extensions → instrumentation}/models/mocking.rb +1 -1
- data/lib/stratagem/instrumentation/models/persistence.rb +9 -0
- data/lib/stratagem/instrumentation/models/persistence/active_record/detect.rb +18 -0
- data/lib/stratagem/{framework_extensions/models/adapters → instrumentation/models/persistence}/active_record/extensions.rb +5 -1
- data/lib/stratagem/{framework_extensions/models/adapters → instrumentation/models/persistence}/active_record/metadata.rb +25 -9
- data/lib/stratagem/{framework_extensions/models/adapters → instrumentation/models/persistence}/active_record/tracing.rb +4 -2
- data/lib/stratagem/instrumentation/models/persistence/common/detect.rb +7 -0
- data/lib/stratagem/{framework_extensions/models/adapters → instrumentation/models/persistence}/common/extensions.rb +0 -0
- data/lib/stratagem/{framework_extensions/models/adapters → instrumentation/models/persistence}/common/metadata.rb +6 -2
- data/lib/stratagem/instrumentation/models/persistence/common/tracing.rb +4 -0
- data/lib/stratagem/instrumentation/models/support_libraries.rb +7 -0
- data/lib/stratagem/{framework_extensions/models/adapters → instrumentation/models/support_libraries}/friendly_id/detect.rb +2 -2
- data/lib/stratagem/{framework_extensions/models/adapters → instrumentation/models/support_libraries}/friendly_id/metadata.rb +2 -2
- data/lib/stratagem/instrumentation/models/support_libraries/state_machine/detect.rb +11 -0
- data/lib/stratagem/instrumentation/models/support_libraries/state_machine/metadata.rb +17 -0
- data/lib/stratagem/{framework_extensions → instrumentation}/models/tracing.rb +2 -2
- data/lib/stratagem/{framework_extensions → instrumentation}/rails.rb +0 -0
- data/lib/stratagem/{framework_extensions → instrumentation}/rails2/action_controller.rb +0 -0
- data/lib/stratagem/{framework_extensions → instrumentation}/rails2/action_mailer.rb +0 -0
- data/lib/stratagem/{framework_extensions → instrumentation}/rails3/parameters.rb +0 -0
- data/lib/stratagem/{framework_extensions → instrumentation}/request_forgery_protection.rb +0 -0
- data/lib/stratagem/model/application.rb +30 -15
- data/lib/stratagem/model/components/controller.rb +2 -2
- data/lib/stratagem/model/components/reference.rb +2 -2
- data/lib/stratagem/model/components/view.rb +1 -1
- data/lib/stratagem/model_builder.rb +19 -8
- data/lib/stratagem/scanner.rb +1 -1
- data/lib/stratagem/site_crawler.rb +4 -2
- data/stratagem.gemspec +7 -7
- data/templates/install/tasks/stratagem.rake +9 -1
- metadata +86 -82
- data/lib/stratagem/framework_extensions.rb +0 -18
- data/lib/stratagem/framework_extensions/models.rb +0 -21
- data/lib/stratagem/framework_extensions/models/adapters/active_record/detect.rb +0 -7
- data/lib/stratagem/framework_extensions/models/adapters/authlogic/extensions.rb +0 -10
- data/lib/stratagem/framework_extensions/models/adapters/authlogic/tracing.rb +0 -4
- data/lib/stratagem/framework_extensions/models/adapters/common/detect.rb +0 -7
- data/lib/stratagem/framework_extensions/models/adapters/common/tracing.rb +0 -4
- data/lib/stratagem/framework_extensions/models/adapters/devise/detect.rb +0 -11
- data/lib/stratagem/framework_extensions/models/adapters/devise/extensions.rb +0 -0
- data/lib/stratagem/framework_extensions/models/adapters/devise/tracing.rb +0 -4
- data/lib/stratagem/framework_extensions/models/adapters/friendly_id/extensions.rb +0 -0
- data/lib/stratagem/framework_extensions/models/adapters/friendly_id/tracing.rb +0 -4
- data/lib/stratagem/framework_extensions/models/adapters/restful_authentication/tracing.rb +0 -4
- data/lib/stratagem/framework_extensions/models/annotations.rb +0 -78
data/lib/stratagem/client.rb
CHANGED
@@ -9,7 +9,7 @@ module Stratagem
|
|
9
9
|
def send(snapshot)
|
10
10
|
Stratagem.logger.debug "Sending report to server"
|
11
11
|
url = URI.parse("#{@authentication.base_url}/snapshots")
|
12
|
-
req = Net::HTTPS::Post.new(url.path)
|
12
|
+
req = Stratagem.ssl? ? Net::HTTPS::Post.new(url.path) : Net::HTTP::Post.new(url.path)
|
13
13
|
|
14
14
|
req.set_form_data({
|
15
15
|
'auth_token' => @authentication.credentials[:token],
|
@@ -17,7 +17,8 @@ module Stratagem
|
|
17
17
|
'timestamp' => snapshot.timestamp.to_i,
|
18
18
|
'model' => snapshot.model.export.to_json
|
19
19
|
}, ';')
|
20
|
-
|
20
|
+
client = Stratagem.ssl? ? Net::HTTPS.new(url.host, url.port) : Net::HTTP.new(url.host, url.port)
|
21
|
+
res = client.start {|http| http.request(req) }
|
21
22
|
puts "response:"
|
22
23
|
case res
|
23
24
|
when Net::HTTPSuccess, Net::HTTPRedirection
|
@@ -75,9 +75,15 @@ module Stratagem::Crawler
|
|
75
75
|
if authentication.login_page.nil?
|
76
76
|
puts "locating login page"
|
77
77
|
puts "testing #{site_models.first.pages.size} pages"
|
78
|
-
site_models.first.pages.
|
79
|
-
|
80
|
-
|
78
|
+
possibilities = site_models.first.pages.select {|page| page.login_form != nil }
|
79
|
+
possibilities.sort! {|a,b| b.inbound_edges(:redirect).size <=> a.inbound_edges(:redirect).size }
|
80
|
+
|
81
|
+
# if the first page has one or more redirects to it then use it; otherwise select with page with the fewest inputs
|
82
|
+
if (possibilities.first.inbound_edges(:redirect).size > 0)
|
83
|
+
return possibilities.first
|
84
|
+
else
|
85
|
+
page = possibilities.sort {|a,b| a.login_form.inputs.size <=> b.login_form.inputs.size }.first
|
86
|
+
if (page)
|
81
87
|
authentication.login_page = page
|
82
88
|
return page
|
83
89
|
end
|
@@ -94,6 +100,7 @@ module Stratagem::Crawler
|
|
94
100
|
|
95
101
|
def login(user)
|
96
102
|
populate_login_form(user).submit {|action,params|
|
103
|
+
p params
|
97
104
|
post(action, params)
|
98
105
|
}
|
99
106
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# Primarily used to fill out login forms rather than trying to fudge the before_filters
|
2
2
|
module Stratagem::Crawler
|
3
3
|
class Form
|
4
|
-
attr_accessor :action, :method, :
|
4
|
+
attr_accessor :action, :method, :buttons, :page
|
5
5
|
attr_reader :inputs, :buttons
|
6
6
|
|
7
7
|
def initialize
|
@@ -70,7 +70,7 @@ module Stratagem::Crawler
|
|
70
70
|
|
71
71
|
def guess_alternate_attribute
|
72
72
|
if (name =~ /(.*)\[(.*)\]/)
|
73
|
-
$
|
73
|
+
$2.to_sym
|
74
74
|
else
|
75
75
|
name.to_sym
|
76
76
|
end
|
@@ -13,12 +13,22 @@ module Stratagem::Crawler
|
|
13
13
|
# this maps to the form action, not the controller action
|
14
14
|
form.action =~ /log[-]*in/ ||
|
15
15
|
form.action =~ /sign[-]*in/ ||
|
16
|
-
|
16
|
+
begin
|
17
|
+
password_field = form.inputs.find {|input| input.type == 'password' }
|
18
|
+
if (password_field)
|
19
|
+
confirmation_field = form.inputs.find {|input| input.name.include?('_confirmation') && (input.name.to_s.sub('_confirmation','') == password_field.name) }
|
20
|
+
confirmation_field.nil?
|
21
|
+
else
|
22
|
+
false
|
23
|
+
end
|
24
|
+
end
|
17
25
|
}.sort {|a,b| a.inputs.size <=> b.inputs.size }
|
18
26
|
possibilities.first
|
19
27
|
end
|
20
28
|
|
21
29
|
def parse_forms(document)
|
30
|
+
return [] if document.nil?
|
31
|
+
|
22
32
|
document.xpath('//form').map do |form_tag|
|
23
33
|
form = Form.new()
|
24
34
|
form.action = form_load_attribute(form_tag, 'action')
|
@@ -49,6 +59,7 @@ module Stratagem::Crawler
|
|
49
59
|
value = (value ? value.value : option_tag.inner_html).strip
|
50
60
|
input << value unless value.empty?
|
51
61
|
end
|
62
|
+
form << input
|
52
63
|
end
|
53
64
|
|
54
65
|
def form_add_input(form, input_tag)
|
@@ -10,7 +10,7 @@ module Stratagem::Crawler
|
|
10
10
|
if (unknown_params.size > 0)
|
11
11
|
resolve_with_convention(unknown_params, resolved_params)
|
12
12
|
resolve_with_instrumentation(route_container, resolved_params)
|
13
|
-
|
13
|
+
resolve_id_with_convention(route_container, unknown_params, resolved_params)
|
14
14
|
log "\tresolved parameter types - #{resolved_params.inspect}"
|
15
15
|
end
|
16
16
|
|
@@ -67,13 +67,27 @@ module Stratagem::Crawler
|
|
67
67
|
unknown_params.delete(param)
|
68
68
|
puts "\t\tresolved #{param} to #{model} using convention"
|
69
69
|
rescue NameError
|
70
|
-
puts
|
71
|
-
puts $!.backtrace
|
72
|
-
# not a model
|
70
|
+
puts "ERROR: #{$!.message}"
|
73
71
|
end
|
74
72
|
end
|
75
73
|
end
|
76
74
|
end
|
77
75
|
|
76
|
+
# resolve the ID parameter by looking at the previous segment of the URL
|
77
|
+
def resolve_id_with_convention(route_container, unknown_params, resolved_params)
|
78
|
+
if (unknown_params.include?('id'))
|
79
|
+
route_container.path.split('/').inject(nil) {|prev,part|
|
80
|
+
if (prev && part == ':id')
|
81
|
+
begin
|
82
|
+
resolved_params['id'] = prev.singularize.camelize.constantize
|
83
|
+
unknown_params.delete('id')
|
84
|
+
rescue
|
85
|
+
puts $!.message
|
86
|
+
end
|
87
|
+
end
|
88
|
+
part
|
89
|
+
}
|
90
|
+
end
|
91
|
+
end
|
78
92
|
end
|
79
93
|
end
|
@@ -14,16 +14,17 @@ module Stratagem::Crawler
|
|
14
14
|
def call_route(route_info, track_invocations=true)
|
15
15
|
begin
|
16
16
|
call_route!(route_info, track_invocations)
|
17
|
-
rescue
|
17
|
+
rescue Exception
|
18
18
|
# TODO - add exception as a response page
|
19
19
|
puts "ERROR: #{$!.message}"
|
20
|
+
puts $!.backtrace
|
20
21
|
end
|
21
22
|
end
|
22
23
|
|
23
24
|
def call_route!(route_info, track_invocations=true)
|
24
25
|
return if route_info.nil?
|
25
26
|
|
26
|
-
puts route_info[:verb].downcase+" "+route_info[:path]
|
27
|
+
puts route_info[:verb].downcase+" "+route_info[:path]+" - #{route_info[:route_container].path}"
|
27
28
|
verb = route_info[:verb].downcase
|
28
29
|
verb = 'get' if verb == '' || verb == 'any'
|
29
30
|
|
@@ -33,6 +34,7 @@ module Stratagem::Crawler
|
|
33
34
|
do_get(route_info)
|
34
35
|
puts "\tresponse code: #{response.code}" if response
|
35
36
|
when 'post'
|
37
|
+
do_post(route_info)
|
36
38
|
when 'put'
|
37
39
|
do_put(route_info)
|
38
40
|
when 'delete'
|
@@ -48,8 +50,10 @@ module Stratagem::Crawler
|
|
48
50
|
invocations.each do |i|
|
49
51
|
puts "\t\t#{i.controller_action} -> #{i.model_class}"
|
50
52
|
end
|
51
|
-
|
53
|
+
|
54
|
+
puts "\tchanges values: #{changes.values.inspect}" if changes.size > 0
|
52
55
|
site_model.add(route_info[:route_container], controller, request, response, invocations, changes) {|redirect_url| redirect_proc.call(redirect_url) }
|
56
|
+
puts "\tadded to site model"
|
53
57
|
end
|
54
58
|
else
|
55
59
|
puts "ERROR: did not call #{route_info.inspect}"
|
@@ -61,9 +65,12 @@ module Stratagem::Crawler
|
|
61
65
|
end
|
62
66
|
|
63
67
|
def do_put(route_info)
|
64
|
-
raise "unable to invoke PUT requests, application must first be crawled with GET requests for phase #{
|
68
|
+
# raise "unable to invoke PUT requests, application must first be crawled with GET requests for phase #{site_model.name}." unless site_model.pages.size > 0
|
65
69
|
|
66
70
|
form = guess_form_for_route(route_info)
|
71
|
+
if (form.nil?)
|
72
|
+
puts "WARNING: could not locate form for route #{route_info[:route_container].path}"
|
73
|
+
end
|
67
74
|
|
68
75
|
params = {}
|
69
76
|
|
@@ -77,15 +84,11 @@ module Stratagem::Crawler
|
|
77
84
|
end
|
78
85
|
end
|
79
86
|
|
80
|
-
p hash_reads
|
81
|
-
|
82
87
|
# let's find out what the method is looking for in the params object
|
83
88
|
models_by_hash_key = infer_models_for_param_reads(route_info[:route_container],hash_reads)
|
84
89
|
params = map_models_to_attributes(models_by_hash_key)
|
85
90
|
|
86
|
-
|
87
|
-
|
88
|
-
guess_unknown_params(models_by_hash_key, params, form)
|
91
|
+
guess_unknown_params(models_by_hash_key, params, form) if form
|
89
92
|
|
90
93
|
# run again with the params
|
91
94
|
puts "PUTTING: #{route_info[:path]} with #{params.inspect}"
|
@@ -95,13 +98,47 @@ module Stratagem::Crawler
|
|
95
98
|
end
|
96
99
|
end
|
97
100
|
|
101
|
+
def do_post(route_info)
|
102
|
+
raise "unable to invoke PUT requests, application must first be crawled with GET requests for phase #{phase}." unless site_model.pages.size > 0
|
103
|
+
|
104
|
+
form = guess_form_for_route(route_info)
|
105
|
+
if (form.nil?)
|
106
|
+
puts "WARNING: could not locate form for route #{route_info[:route_container].path}"
|
107
|
+
end
|
108
|
+
|
109
|
+
params = {}
|
110
|
+
|
111
|
+
# note: this should fail to generate anything meaningful, as we have not yet set up the parameters
|
112
|
+
hash_reads = Hash.track_parameter_reads do
|
113
|
+
begin
|
114
|
+
post route_info[:path], params
|
115
|
+
rescue
|
116
|
+
# TODO - log error as page response
|
117
|
+
puts "ERROR: #{response.code}"
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
# let's find out what the method is looking for in the params object
|
122
|
+
models_by_hash_key = infer_models_for_param_reads(route_info[:route_container],hash_reads)
|
123
|
+
params = map_models_to_attributes(models_by_hash_key)
|
124
|
+
|
125
|
+
guess_unknown_params(models_by_hash_key, params, form) if form
|
126
|
+
|
127
|
+
# run again with the params
|
128
|
+
puts "POSTING: #{route_info[:path]} with #{params.inspect}"
|
129
|
+
|
130
|
+
invocation_delta = model_invocations_for_request(:write) do
|
131
|
+
post route_info[:path], params
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
98
135
|
private
|
99
136
|
|
100
137
|
def guess_unknown_params(models_by_hash_key, known_params, form)
|
101
138
|
(form.parameter_keys - IGNORE_PARAMETERS) .each {|path_s|
|
102
139
|
path = path_s.split('[')
|
103
140
|
path.last.gsub!(']', '')
|
104
|
-
value = known_params
|
141
|
+
value = known_params || {}
|
105
142
|
model = nil
|
106
143
|
path.each do |key|
|
107
144
|
key = key.to_sym
|
@@ -137,8 +174,11 @@ module Stratagem::Crawler
|
|
137
174
|
site_model.pages.each do |page|
|
138
175
|
page.forms.each do |form|
|
139
176
|
usable = route_info[:route_container].responds_to?(form.action, form.implied_method || form.method)
|
140
|
-
|
141
|
-
|
177
|
+
usable ||= begin
|
178
|
+
(route_info[:path].sub(/\.\(\:format\)*/, '') == form.action) &&
|
179
|
+
((form.implied_method || form.method).to_s.downcase == route_info[:verb].to_s.downcase)
|
180
|
+
end
|
181
|
+
puts "\tform: #{form.action} - #{form.implied_method || form.method} - #{usable}"
|
142
182
|
forms << form if (usable)
|
143
183
|
end
|
144
184
|
end
|
@@ -183,9 +223,12 @@ module Stratagem::Crawler
|
|
183
223
|
if (invocation.model_instance)
|
184
224
|
model = application_model.models.find {|m| m.klass == invocation.model_instance.class }
|
185
225
|
|
186
|
-
puts "\t\t#{invocation.model_class}.#{invocation.method} - #{invocation.model_instance}"
|
226
|
+
puts "\t\t#{invocation.model_class}.#{invocation.method} - #{invocation.model_instance} - #{invocation.model_instance.id}"
|
227
|
+
ids = aquifer.instances_of(invocation.model_instance.class).map {|i| i.id }
|
228
|
+
puts "\t\tinstances: #{ids.inspect}"
|
187
229
|
prior = aquifer.instances_of(invocation.model_instance.class).find {|m| m.id == invocation.model_instance.id }
|
188
230
|
post = invocation.model_instance
|
231
|
+
prior ||= post
|
189
232
|
attribute_names = (prior.stratagem.attribute_names + prior.stratagem.foreign_keys)
|
190
233
|
changes[model] = attribute_names.select {|an|
|
191
234
|
begin
|
@@ -216,7 +259,7 @@ module Stratagem::Crawler
|
|
216
259
|
yield path
|
217
260
|
else
|
218
261
|
combinations = segment_values[0].product(*segment_values.slice(1,segment_values.size-1))
|
219
|
-
combinations.each do |combination|
|
262
|
+
combinations.uniq.each do |combination|
|
220
263
|
url = path.clone
|
221
264
|
route.segment_keys.each_with_index {|segment_key,i| url.gsub!(':'+segment_key.to_s, combination[i].to_s) }
|
222
265
|
yield url
|
@@ -232,7 +275,7 @@ module Stratagem::Crawler
|
|
232
275
|
|
233
276
|
|
234
277
|
i = 12345
|
235
|
-
insert_values = (
|
278
|
+
insert_values = (route_container.segment_keys - [:format]).map {|segment_key|
|
236
279
|
model = parameter_types[segment_key.to_s]
|
237
280
|
value = nil
|
238
281
|
if (model)
|
@@ -250,7 +293,6 @@ module Stratagem::Crawler
|
|
250
293
|
permutation = {:verb => verb, :path => path, :route_container => route_container}
|
251
294
|
routes << permutation
|
252
295
|
end
|
253
|
-
|
254
296
|
[routes, params]
|
255
297
|
end
|
256
298
|
|
@@ -91,21 +91,29 @@ module Stratagem::Crawler::Session
|
|
91
91
|
|
92
92
|
def print
|
93
93
|
# print out pages and inbound / outbound links
|
94
|
+
# debugger
|
94
95
|
site_model.pages.each do |page|
|
95
96
|
title = page.title
|
96
97
|
title ||= page.redirected_to.url if page.redirected_to
|
97
98
|
title ||= page.response.code
|
98
99
|
log "Page: #{page.url} - #{title} - #{page.response.code}"
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
100
|
+
begin
|
101
|
+
page.outbound_edges.each do |edge|
|
102
|
+
log "\tout: #{edge.to.url} - #{edge.to.title} - #{edge.to.route}"
|
103
|
+
end
|
104
|
+
page.inbound_edges.each do |edge|
|
105
|
+
log "\tin: #{edge.from.url} - #{edge.from.title}"
|
106
|
+
end
|
107
|
+
rescue Exception
|
108
|
+
puts $!.message
|
109
|
+
puts $!.backtrace
|
104
110
|
end
|
105
111
|
end
|
112
|
+
puts "end of site model"
|
106
113
|
end
|
107
114
|
|
108
115
|
def crawl(verbs=[:any,:get])
|
116
|
+
puts "crawling site for verbs #{verbs.inspect}"
|
109
117
|
verbs = [verbs] unless verbs.kind_of?(Array)
|
110
118
|
|
111
119
|
# grab all pages independently
|
@@ -17,6 +17,7 @@ module Stratagem::Crawler
|
|
17
17
|
:pages => @pages.map {|page| page.export },
|
18
18
|
:edges => @edges.map {|edge| edge.export },
|
19
19
|
:authentication => authentication.nil? ? nil : {
|
20
|
+
:authenticated_user_id => authentication.authenticated_with.object_id,
|
20
21
|
:success => authentication.success,
|
21
22
|
:login_page_external_id => authentication.login_page.object_id,
|
22
23
|
:response_page_external_id => authentication.response_page.object_id,
|
@@ -74,12 +75,13 @@ module Stratagem::Crawler
|
|
74
75
|
attr_accessor :method
|
75
76
|
attr_accessor :redirected_to
|
76
77
|
attr_accessor :document
|
78
|
+
attr_accessor :response_body
|
77
79
|
|
78
80
|
def initialize(site_model, controller, request, response, invocations, model_changes, &block)
|
79
81
|
@site_model = site_model
|
80
82
|
@invocations = invocations
|
81
83
|
@model_changes = model_changes
|
82
|
-
@authenticity_checked = controller.authenticity_checked?
|
84
|
+
@authenticity_checked = (controller && controller.methods.include?(:authenticity_checked?)) ? controller.authenticity_checked? : true
|
83
85
|
init(request, response, &block)
|
84
86
|
end
|
85
87
|
|
@@ -98,7 +100,8 @@ module Stratagem::Crawler
|
|
98
100
|
:references => @invocations.map {|i| i.to_reference.export },
|
99
101
|
:model_changes => Hash[@model_changes.map {|model,changes| [model.object_id, changes] }].to_json,
|
100
102
|
:authenticity_checked => @authenticity_checked,
|
101
|
-
:parameters => @request.parameters.to_json
|
103
|
+
:parameters => @request.parameters.to_json,
|
104
|
+
:response_body => @response_body
|
102
105
|
}
|
103
106
|
h
|
104
107
|
end
|
@@ -109,7 +112,12 @@ module Stratagem::Crawler
|
|
109
112
|
@url = request.url
|
110
113
|
@path = request.path
|
111
114
|
@method = request.method
|
112
|
-
|
115
|
+
begin
|
116
|
+
@document = Nokogiri::HTML(response.body)
|
117
|
+
rescue
|
118
|
+
puts "ERROR: Could not parse html: #{$!.message} - #{response.body}"
|
119
|
+
end
|
120
|
+
@response_body = response.body
|
113
121
|
self.redirected_to = block.call(response.redirect_url) if response.redirect?
|
114
122
|
end
|
115
123
|
|
@@ -126,11 +134,15 @@ module Stratagem::Crawler
|
|
126
134
|
|
127
135
|
def forms
|
128
136
|
@forms ||= begin
|
129
|
-
|
130
|
-
|
131
|
-
|
137
|
+
if (@document)
|
138
|
+
forms = self.parse_forms(@document)
|
139
|
+
forms.each do |form|
|
140
|
+
form.page = self
|
141
|
+
end
|
142
|
+
forms
|
143
|
+
else
|
144
|
+
[]
|
132
145
|
end
|
133
|
-
forms
|
134
146
|
end
|
135
147
|
end
|
136
148
|
|
@@ -151,7 +163,7 @@ module Stratagem::Crawler
|
|
151
163
|
end
|
152
164
|
|
153
165
|
def title
|
154
|
-
|
166
|
+
if ((@document) && !(@title))
|
155
167
|
title = (@document/'head title').first
|
156
168
|
@title = title.inner_html if title
|
157
169
|
end
|
@@ -2,8 +2,8 @@ class Object
|
|
2
2
|
def methods_include?(name)
|
3
3
|
methods.include?(name.to_sym) || methods.include?(name.to_s)
|
4
4
|
end
|
5
|
-
|
6
|
-
def self.
|
5
|
+
|
6
|
+
def self.sg_subclasses
|
7
7
|
classes = []
|
8
8
|
ObjectSpace.each_object(Class) do |c|
|
9
9
|
next unless c.superclass == self || c.ancestors.include?(self)
|
@@ -7,8 +7,8 @@ class String
|
|
7
7
|
match = false
|
8
8
|
[
|
9
9
|
Regexp.compile("^#{token}$", true),
|
10
|
-
Regexp.compile("^#{token}[^A-Za-z0-
|
11
|
-
Regexp.compile("[^A-Za-z0-
|
10
|
+
Regexp.compile("^#{token}[^A-Za-z0-9_\-]*", true),
|
11
|
+
Regexp.compile("[^A-Za-z0-9_\-]*#{token}$", true),
|
12
12
|
].each do |regex|
|
13
13
|
if (regex.match(self))
|
14
14
|
match = true
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Stratagem::Instrumentation; end
|
2
|
+
|
3
|
+
require 'stratagem/instrumentation/rails'
|
4
|
+
require 'stratagem/instrumentation/method_invocation'
|
5
|
+
require 'stratagem/instrumentation/models'
|
6
|
+
require 'stratagem/instrumentation/request_forgery_protection'
|
7
|
+
|
8
|
+
if (Stratagem.rails_3?)
|
9
|
+
require 'stratagem/instrumentation/rails3/parameters'
|
10
|
+
elsif (Stratagem.rails_2?)
|
11
|
+
require 'stratagem/instrumentation/rails2/action_controller'
|
12
|
+
require 'stratagem/instrumentation/rails2/action_mailer'
|
13
|
+
else
|
14
|
+
raise "Unsupported Rails version #{Stratagem.rails_version}"
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
|