stratagem 0.1.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (101) hide show
  1. data/Manifest +99 -0
  2. data/Rakefile +17 -0
  3. data/bin/stratagem +10 -0
  4. data/init.rb +2 -0
  5. data/lib/bootstrap.rb +31 -0
  6. data/lib/stratagem/authentication.rb +64 -0
  7. data/lib/stratagem/auto_mock/aquifer.rb +86 -0
  8. data/lib/stratagem/auto_mock/factory.rb +213 -0
  9. data/lib/stratagem/auto_mock/value_generator.rb +174 -0
  10. data/lib/stratagem/auto_mock.rb +6 -0
  11. data/lib/stratagem/blocker.rb +16 -0
  12. data/lib/stratagem/client.rb +32 -0
  13. data/lib/stratagem/command.rb +13 -0
  14. data/lib/stratagem/commands/analyze.rb +22 -0
  15. data/lib/stratagem/commands/base.rb +11 -0
  16. data/lib/stratagem/commands/devel_crawl.rb +27 -0
  17. data/lib/stratagem/commands/devel_mock.rb +10 -0
  18. data/lib/stratagem/commands.rb +7 -0
  19. data/lib/stratagem/crawler/authentication.rb +109 -0
  20. data/lib/stratagem/crawler/form.rb +101 -0
  21. data/lib/stratagem/crawler/html_utils.rb +92 -0
  22. data/lib/stratagem/crawler/session.rb +296 -0
  23. data/lib/stratagem/crawler/site_model.rb +138 -0
  24. data/lib/stratagem/crawler/trace_utils.rb +10 -0
  25. data/lib/stratagem/crawler.rb +9 -0
  26. data/lib/stratagem/extensions/class.rb +9 -0
  27. data/lib/stratagem/extensions/hash.rb +16 -0
  28. data/lib/stratagem/extensions/module.rb +11 -0
  29. data/lib/stratagem/extensions/object.rb +15 -0
  30. data/lib/stratagem/extensions/red_parse.rb +86 -0
  31. data/lib/stratagem/extensions/string.rb +20 -0
  32. data/lib/stratagem/extensions.rb +6 -0
  33. data/lib/stratagem/framework_extensions/controllers/action_controller.rb +10 -0
  34. data/lib/stratagem/framework_extensions/controllers/action_mailer.rb +12 -0
  35. data/lib/stratagem/framework_extensions/controllers.rb +5 -0
  36. data/lib/stratagem/framework_extensions/models/adapters/active_model/detect.rb +7 -0
  37. data/lib/stratagem/framework_extensions/models/adapters/active_model/extensions.rb +35 -0
  38. data/lib/stratagem/framework_extensions/models/adapters/active_model/metadata.rb +103 -0
  39. data/lib/stratagem/framework_extensions/models/adapters/active_model/tracing.rb +50 -0
  40. data/lib/stratagem/framework_extensions/models/adapters/authlogic/detect.rb +11 -0
  41. data/lib/stratagem/framework_extensions/models/adapters/authlogic/extensions.rb +10 -0
  42. data/lib/stratagem/framework_extensions/models/adapters/authlogic/metadata.rb +30 -0
  43. data/lib/stratagem/framework_extensions/models/adapters/authlogic/tracing.rb +4 -0
  44. data/lib/stratagem/framework_extensions/models/adapters/common/authentication_metadata.rb +21 -0
  45. data/lib/stratagem/framework_extensions/models/adapters/restful_authentication/detect.rb +13 -0
  46. data/lib/stratagem/framework_extensions/models/adapters/restful_authentication/extensions.rb +19 -0
  47. data/lib/stratagem/framework_extensions/models/adapters/restful_authentication/metadata.rb +30 -0
  48. data/lib/stratagem/framework_extensions/models/adapters/restful_authentication/tracing.rb +4 -0
  49. data/lib/stratagem/framework_extensions/models/annotations.rb +79 -0
  50. data/lib/stratagem/framework_extensions/models/detect.rb +7 -0
  51. data/lib/stratagem/framework_extensions/models/metadata.rb +85 -0
  52. data/lib/stratagem/framework_extensions/models/mocking.rb +23 -0
  53. data/lib/stratagem/framework_extensions/models/tracing.rb +71 -0
  54. data/lib/stratagem/framework_extensions/models.rb +21 -0
  55. data/lib/stratagem/framework_extensions/rails.rb +8 -0
  56. data/lib/stratagem/framework_extensions.rb +6 -0
  57. data/lib/stratagem/interface/browser.rb +37 -0
  58. data/lib/stratagem/interface/public/images/backgrounds/content.png +0 -0
  59. data/lib/stratagem/interface/public/images/backgrounds/shadow.png +0 -0
  60. data/lib/stratagem/interface/public/javascripts/jquery-1.4.2.min.js +154 -0
  61. data/lib/stratagem/interface/public/javascripts/stratagem.js +27 -0
  62. data/lib/stratagem/interface/public/javascripts/stratagem_debug.js +53 -0
  63. data/lib/stratagem/interface/public/stylesheets/960.css +1 -0
  64. data/lib/stratagem/interface/public/stylesheets/reset.css +10 -0
  65. data/lib/stratagem/interface/public/stylesheets/stratagem.css +20 -0
  66. data/lib/stratagem/interface/public/stylesheets/stratagem_debug.css +20 -0
  67. data/lib/stratagem/interface/views/debug.haml +43 -0
  68. data/lib/stratagem/interface/views/index.haml +35 -0
  69. data/lib/stratagem/labs/auto_mock.rb +7 -0
  70. data/lib/stratagem/labs/crawler.rb +0 -0
  71. data/lib/stratagem/logger.rb +46 -0
  72. data/lib/stratagem/model/application.rb +157 -0
  73. data/lib/stratagem/model/components/base.rb +55 -0
  74. data/lib/stratagem/model/components/controller.rb +118 -0
  75. data/lib/stratagem/model/components/model.rb +170 -0
  76. data/lib/stratagem/model/components/reference.rb +30 -0
  77. data/lib/stratagem/model/components/route.rb +53 -0
  78. data/lib/stratagem/model/components/static_file.rb +18 -0
  79. data/lib/stratagem/model/components/view.rb +186 -0
  80. data/lib/stratagem/model/parse_util.rb +61 -0
  81. data/lib/stratagem/model.rb +12 -0
  82. data/lib/stratagem/model_builder.rb +146 -0
  83. data/lib/stratagem/recipes/deploy.rb +30 -0
  84. data/lib/stratagem/scan/checks/capistrano/secure_deploy.rb +43 -0
  85. data/lib/stratagem/scan/checks/email_address.rb +15 -0
  86. data/lib/stratagem/scan/checks/error_pages.rb +25 -0
  87. data/lib/stratagem/scan/checks/filter_parameter_logging.rb +6 -0
  88. data/lib/stratagem/scan/checks/mongo_mapper/base.rb +19 -0
  89. data/lib/stratagem/scan/checks/mongo_mapper/foreign_keys_exposed.rb +32 -0
  90. data/lib/stratagem/scan/checks/routes.rb +16 -0
  91. data/lib/stratagem/scan/checks/ssl/secure_login_page.rb +19 -0
  92. data/lib/stratagem/scan/checks/ssl/secure_login_submit.rb +18 -0
  93. data/lib/stratagem/scan/result.rb +45 -0
  94. data/lib/stratagem/scan.rb +19 -0
  95. data/lib/stratagem/scanner.rb +32 -0
  96. data/lib/stratagem/site_crawler.rb +47 -0
  97. data/lib/stratagem/snapshot.rb +33 -0
  98. data/lib/stratagem.rb +77 -0
  99. data/lib/tasks/_old_stratagem.rake +99 -0
  100. data/stratagem.gemspec +56 -0
  101. metadata +380 -0
@@ -0,0 +1,296 @@
1
+ require 'nokogiri'
2
+
3
+ require 'action_pack'
4
+ require 'action_controller'
5
+
6
+ class CrawlError < StratagemError; end
7
+
8
+ # require 'rack/lint'
9
+ # module Rack
10
+ # # Rack::Lint validates your application and the requests and
11
+ # # responses according to the Rack spec.
12
+ #
13
+ # class Lint
14
+ # alias_method :old_call, :call
15
+ #
16
+ # def call(env)
17
+ # data = env['rack.input']
18
+ # data.set_encoding(Encoding::ASCII_8BIT) if data.respond_to?(:set_encoding)
19
+ #
20
+ # status, headers, body = old_call(env)
21
+ # body.close # fix for Rack
22
+ # [status,headers,body]
23
+ # end
24
+ # end
25
+ # end
26
+
27
+ PHASES = [:unauthenticated,:authenticated]
28
+
29
+ module Stratagem::Crawler::Session
30
+ include ActionController::Integration::Runner
31
+ include Stratagem::Crawler::HtmlUtils
32
+ include Stratagem::Crawler::TraceUtils
33
+ include Stratagem::Crawler::Authentication
34
+
35
+ def log(msg)
36
+ Stratagem.logger.debug msg
37
+ end
38
+
39
+ def crawler_session(application_model=nil)
40
+ @model = application_model
41
+ @model ||= Stratagem::ModelBuilder.new.run
42
+ @redirect_proc = Proc.new {|redirect_url| handle_redirect(redirect_url) }
43
+ @parameter_types = {} # routecontainer -> {:route_segment => Model, :route_segment => Model}
44
+ open_session do |session|
45
+ @session = session
46
+ phase(:unauthenticated)
47
+ yield
48
+ end
49
+ end
50
+
51
+ def application_model
52
+ @model
53
+ end
54
+
55
+ def site_models
56
+ @site_models ||= {} # builds models of the site for various phases of analysis, see PHASES
57
+ end
58
+
59
+ def site_model
60
+ raise Stratagem::Crawler::CrawlError.new("Phase not specified") unless @current_model
61
+ @current_model
62
+ end
63
+
64
+ def phase(new_phase)
65
+ @current_phase = new_phase
66
+ @current_model = site_models[@current_phase] ||= Stratagem::Crawler::SiteModel.new
67
+ end
68
+
69
+ def phases
70
+ site_models
71
+ end
72
+
73
+ def display
74
+ # print out pages and inbound / outbound links
75
+ site_model.pages.each do |page|
76
+ log "Page: #{page.url} - #{page.title} - #{page.response.code}"
77
+ page.outbound_edges.each do |edge|
78
+ log "\tout: #{edge.to.url} - #{edge.to.title} - #{edge.to.route}"
79
+ end
80
+ page.inbound_edges.each do |edge|
81
+ log "\tin: #{edge.from.url} - #{edge.from.title}"
82
+ end
83
+ end
84
+ end
85
+
86
+ def crawl
87
+ # grab all pages independently
88
+ @model.routes.invalid.each {|route_container|
89
+ puts "skipping invalid route #{route_container.route.to_s}"
90
+ }
91
+
92
+ authentication_controller = nil
93
+ if (@current_phase == :authenticated)
94
+ route = @model.routes.recognize(authentication.login_page)
95
+ authentication_controller = route.controller
96
+ end
97
+
98
+ @model.routes.each {|route_container|
99
+ if authentication_controller && route_container.controller && (route_container.controller.klass == authentication_controller.klass)
100
+ log "Skipping authentication routes #{route_container.route.to_s}"
101
+ else
102
+ visit(route_container) unless @model.routes.invalid.include?(route_container)
103
+ end
104
+ }
105
+
106
+ # establish edges on site graph
107
+ site_model.pages.each do |page|
108
+ site_model.add_edge(page, page.redirected_to, :redirect) if page.redirected?
109
+ end
110
+
111
+ site_model
112
+ end
113
+
114
+ private
115
+
116
+ def visit(route_container)
117
+ puts "visiting #{route_container.route}"
118
+ build_urls(route_container).each do |route_info|
119
+ call_route(route_container, route_info)
120
+ end
121
+ end
122
+
123
+ def call_route(route, route_info)
124
+ puts 'CALLING: .'+route_info[:verb].downcase+". - "+route_info[:path]
125
+ verb = route_info[:verb].downcase
126
+ verb = 'get' if verb == '' || verb == 'any'
127
+ case verb
128
+ when 'get'
129
+ do_get(route, route_info[:path])
130
+ puts response.code if response
131
+ when 'post'
132
+ when 'put'
133
+ when 'delete'
134
+ else
135
+ raise "Unsupported verb: #{route[:verb]}"
136
+ end
137
+ end
138
+
139
+ # Builds a list of string URLs for a given route. This is done
140
+ # by replacing :xyz_id segments in the route with known values
141
+ # from the well
142
+ def build_urls(route_container)
143
+ urls = []
144
+ route = route_container.route
145
+ parameter_types = (@parameter_types[route_container] ||= resolve_parameter_types(route_container))
146
+ route_infos, params = build_url(route_container, parameter_types)
147
+ puts "route: #{route_container.route.to_s} permutations:"
148
+ route_infos.each do |info|
149
+ puts "\t#{info[:path]}"
150
+ end
151
+ route_infos
152
+ end
153
+
154
+ def url_permutations(meta_segments, segment_stack=[], &block)
155
+ if (segment_stack.size == meta_segments.size)
156
+ yield segment_stack
157
+ else
158
+ cursor = segment_stack.size
159
+ options = meta_segments[cursor]
160
+ if (options.kind_of?(Array))
161
+ options.each do |option|
162
+ url_permutations(meta_segments, segment_stack + [option], &block)
163
+ end
164
+ else
165
+ url_permutations(meta_segments, segment_stack + [options], &block)
166
+ end
167
+ end
168
+ end
169
+
170
+ def build_url(route_container, parameter_types={})
171
+ params = {}
172
+ route = route_container.route
173
+ name = route.to_s
174
+ verb = route.conditions[:method].to_s
175
+
176
+ parameter_types ||= {}
177
+
178
+ i = 12345
179
+ segs = route.segments.inject([]) {|accumulated,segment|
180
+ s = segment.to_s
181
+ if (s =~ /^:/)
182
+ model = parameter_types[s]
183
+ value = nil
184
+ if (model)
185
+ value = (Stratagem::AutoMock::Aquifer.instance.instances_of model).map {|inst|
186
+ attr_name = s.gsub(/^:/, '').to_sym
187
+ if inst.methods_include?(attr_name)
188
+ puts "#{attr_name} is a method on the object"
189
+ inst.send(attr_name)
190
+ else
191
+ puts "#{attr_name} is being mapped to the id on the object"
192
+ inst.id
193
+ end
194
+ }
195
+ else
196
+ i += 1
197
+ value = [i]
198
+ end
199
+ accumulated << value
200
+ params[s] = value
201
+ else
202
+ accumulated << s
203
+ end
204
+ accumulated
205
+ }
206
+
207
+ routes = []
208
+ reqs = route.requirements.empty? ? "" : route.requirements.inspect
209
+ url_permutations(segs) do |segments|
210
+ path = segments.join('').gsub('(.:format)', '').gsub(/\/$/, '')
211
+ permutation = {:name => name, :verb => verb, :segs => segs, :reqs => reqs, :path => path}
212
+ routes << permutation
213
+ end
214
+
215
+ [routes, params]
216
+ end
217
+
218
+ def handle_redirect(redirect_url)
219
+ existing_pages = site_model.pages_for(response.redirect_url)
220
+ if (existing_pages.size > 0)
221
+ existing_pages.first
222
+ else
223
+ invocation_delta = model_invocations_for_request do
224
+ get redirect_url
225
+ end
226
+
227
+ site_model.add(nil, response) {|redirect_url|
228
+ # TODO - record as bug!
229
+ puts "recursive redirect #{redirect_url}"
230
+ }
231
+ end
232
+ end
233
+
234
+ def do_get(route,path)
235
+ begin
236
+ get path
237
+ site_model.add(route, response) {|redirect_url| @redirect_proc.call(redirect_url) }
238
+ rescue
239
+ puts $!.message
240
+ puts path
241
+ #puts $!.backtrace
242
+ end
243
+ end
244
+
245
+ def resolve_parameter_types(route_container)
246
+ puts "resolving parameter types for #{route_container.route}"
247
+ resolved_parameters = {}
248
+ route_infos, params = build_url(route_container, resolved_parameters)
249
+ route_info = route_infos.first
250
+ unknown_params = params.keys
251
+ puts "unknown params: #{unknown_params}"
252
+ progress = nil
253
+ while ((unknown_params.size > 0) && (progress.nil? || (progress > 0)))
254
+ progress = 0
255
+
256
+ # p route_infos
257
+ # puts "---"
258
+ delta = model_invocations_for_request do
259
+ call_route(route_container, route_info)
260
+ end
261
+
262
+ puts "delta - #{delta.size}"
263
+ #p delta
264
+
265
+ unknown_params.clone.each do |key|
266
+ value = params[key]
267
+ value_s = params[key].map {|v| v.to_s }
268
+ delta.each do |invocation|
269
+ puts "#{route_info[:path]} - #{invocation.model_class.name} - #{invocation.method} - #{invocation.args.inspect} - #{value_s}"
270
+
271
+ # TODO inspect is a hack, refactor
272
+ if (invocation.args.include?(value.first)) || (invocation.args.inspect.include?('"'+value.first.to_s+'"'))
273
+ # found match
274
+
275
+ puts "\tresolved #{key} to #{invocation.model_class}"
276
+ unknown_params.delete(key)
277
+ resolved_parameters[key] = invocation.model_class
278
+ progress += 1
279
+
280
+ break
281
+ end
282
+ end
283
+ end
284
+
285
+ route_infos, params = build_url(route_container, resolved_parameters)
286
+ route_info = route_infos.first
287
+ end
288
+ if (resolved_parameters.size > 0)
289
+ resolved_parameters
290
+ else
291
+ nil
292
+ end
293
+ end
294
+
295
+
296
+ end
@@ -0,0 +1,138 @@
1
+ module Stratagem::Crawler
2
+ class SiteModel
3
+ include Stratagem::Crawler::HtmlUtils
4
+
5
+ attr_reader :pages, :edges
6
+
7
+ def initialize
8
+ @pages = []
9
+ @edges = []
10
+ end
11
+
12
+ def export
13
+ {
14
+ :pages => @pages.map {|page| page.export },
15
+ :edges => @edges.map {|edge| edge.export }
16
+ }
17
+ end
18
+
19
+ def add_edge(from,to,type)
20
+ self.edges << Edge.new(from,to,type)
21
+ end
22
+
23
+ def add(route, response, &block)
24
+ page = Page.new(self, response, &block)
25
+ self.pages << page
26
+ page
27
+ end
28
+
29
+ def pages_for(id)
30
+ if (id.kind_of?(String))
31
+ pages.select {|page| page.url == id }
32
+ else
33
+ pages.select {|page| page.route == id }
34
+ end
35
+ end
36
+
37
+ end
38
+
39
+ class Edge
40
+ # type -> :link, :redirect,
41
+ attr_accessor :from, :to, :type
42
+
43
+ def initialize(from, to, type)
44
+ @from = from
45
+ @to = to
46
+ @type = type
47
+ end
48
+
49
+ def export
50
+ {
51
+ :from => from.object_id,
52
+ :to => to.object_id,
53
+ :type => type
54
+ }
55
+ end
56
+ end
57
+
58
+ class Page
59
+ include Stratagem::Crawler::HtmlUtils
60
+
61
+ attr_reader :response
62
+
63
+ attr_accessor :url
64
+ attr_accessor :path
65
+ attr_accessor :method
66
+ attr_accessor :redirected_to
67
+ attr_accessor :document
68
+
69
+ def initialize(site_model, response, &block)
70
+ @site_model = site_model
71
+ init(response, &block)
72
+ end
73
+
74
+ def route
75
+ Stratagem::Model::Application.instance.routes.recognize(self)
76
+ end
77
+
78
+ def export
79
+ {
80
+ :external_id => self.object_id,
81
+ :url => url,
82
+ :path => path,
83
+ :method => method,
84
+ :redirected_to_page_external_id => redirected_to ? redirected_to.object_id : nil,
85
+ :route_external_id => route.object_id
86
+ }
87
+ end
88
+
89
+ def init(response, &block)
90
+ @response = response.clone
91
+ @url = response.request.url
92
+ @path = response.request.path
93
+ @method = response.request.method
94
+ @document = Nokogiri::HTML(response.body)
95
+ self.redirected_to = block.call(response.redirect_url) if response.redirect?
96
+ end
97
+
98
+ def reload(&block)
99
+ # TODO - should support all the verbs and params, but
100
+ # hack together for now to reload the authenticity token
101
+ response = yield url
102
+ init(response) {|redirected_to| }
103
+ end
104
+
105
+ def redirected?
106
+ !self.redirected_to.nil?
107
+ end
108
+
109
+ def forms
110
+ self.parse_forms(@document)
111
+ end
112
+
113
+ def login_form
114
+ self.find_login_form(@document)
115
+ end
116
+
117
+ def to_html
118
+ @document.to_html
119
+ end
120
+
121
+ def outbound_edges(type=nil)
122
+ @site_model.edges.select {|edge| edge.from == self && (type.nil? || (type == edge.type)) }
123
+ end
124
+
125
+ def inbound_edges(type=nil)
126
+ @site_model.edges.select {|edge| (edge.to == self) && (type.nil? || (type == edge.type)) }
127
+ end
128
+
129
+ def title
130
+ unless @title
131
+ title = (@document/'head title').first
132
+ @title = title.inner_html if title
133
+ end
134
+ @title
135
+ end
136
+ end
137
+
138
+ end
@@ -0,0 +1,10 @@
1
+ module Stratagem::Crawler
2
+ module TraceUtils
3
+ def model_invocations_for_request()
4
+ prior_invocations = ActiveRecord::Base.stratagem.invocations_audit.clone
5
+ yield
6
+ post_invocations = ActiveRecord::Base.stratagem.invocations_audit.clone
7
+ delta = post_invocations - prior_invocations
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,9 @@
1
+ module Stratagem::Crawler
2
+ end
3
+
4
+ require 'stratagem/crawler/form'
5
+ require 'stratagem/crawler/trace_utils'
6
+ require 'stratagem/crawler/html_utils'
7
+ require 'stratagem/crawler/authentication'
8
+ require 'stratagem/crawler/session'
9
+ require 'stratagem/crawler/site_model'
@@ -0,0 +1,9 @@
1
+ class Class
2
+ def classes
3
+ list = [self]
4
+ c = self
5
+ list << c while ((c = c.superclass) != nil)
6
+ list
7
+ end
8
+ end
9
+
@@ -0,0 +1,16 @@
1
+ class Hash
2
+ alias_method :ruby_get, :[]
3
+ attr_reader :hash_reads, :hash_writes
4
+
5
+ def [](name)
6
+ (@hash_reads ||= []) << name if (@auditing)
7
+ ruby_get name
8
+ end
9
+
10
+ def enable_auditing
11
+ @auditing = true
12
+ end
13
+
14
+ # def []=
15
+ # end
16
+ end
@@ -0,0 +1,11 @@
1
+ class Module
2
+ def subclasses
3
+ classes = []
4
+ ObjectSpace.each_object(Class) do |c|
5
+ next unless c.superclass == self || c.ancestors.include?(self)
6
+ next if c == self
7
+ classes << c
8
+ end
9
+ classes
10
+ end
11
+ end
@@ -0,0 +1,15 @@
1
+ class Object
2
+ def methods_include?(name)
3
+ methods.include?(name.to_sym) || methods.include?(name.to_s)
4
+ end
5
+
6
+ def self.subclasses
7
+ classes = []
8
+ ObjectSpace.each_object(Class) do |c|
9
+ next unless c.superclass == self || c.ancestors.include?(self)
10
+ next if c == self
11
+ classes << c
12
+ end
13
+ classes
14
+ end
15
+ end
@@ -0,0 +1,86 @@
1
+ class RedParse::Node
2
+ def talking_about?(model)
3
+ talking_about = false
4
+
5
+ if self.receiver.methods_include?(:name)
6
+ if ((self.receiver) && self.receiver.name == model.klass.name)
7
+ # puts "\treceiver name #{self.receiver.name} is equal to #{model.klass.name}"
8
+ talking_about = true
9
+ elsif (self.receiver)
10
+ name = self.receiver.name
11
+ # if it's lowercase then it's possibly referencing an association
12
+ if (name.downcase == name)
13
+ # look through the models to see if one has an association with this name and class
14
+ Stratagem::Model::Application.instance.models.each do |app_model|
15
+ talking_about = app_model.association_match?(name, model)
16
+ break if talking_about
17
+ end
18
+ end
19
+ end
20
+ end
21
+
22
+ talking_about
23
+ end
24
+
25
+ # iterates the node and figures out the class of the leaf that a call is talking about
26
+ def dereference
27
+ # recursion is evil
28
+ path = []
29
+ current_node = self
30
+ # puts "current:#{current_node.inspect}"
31
+ if (current_node.kind_of?(RedParse::VarNode))
32
+ path << current_node.name if current_node.methods_include?(:name)
33
+ else
34
+ while (current_node.methods_include?(:receiver) && (current_node = current_node.receiver) != nil)
35
+ path << current_node.name if current_node.methods_include?(:name)
36
+ end
37
+ end
38
+ # p path
39
+ previous = nil
40
+ path.reverse!
41
+ path.map! {|element|
42
+ new_val = element
43
+ if (element.downcase != element)
44
+ # class?
45
+ begin
46
+ new_val = Class.class_eval(element)
47
+ rescue
48
+ logger.error "Unable to load class #{element} in #{path.inspect}"
49
+ end
50
+ elsif (element.pluralize == element)
51
+ # collection?
52
+ if (previous)
53
+ if (previous.kind_of?(Class))
54
+ # look up the loaded model of the class
55
+ model = Stratagem::Model::Application.instance.models.find {|m| m.klass == previous }
56
+ if (model)
57
+ match = previous.reflect_on_all_associations.find {|assoc| assoc.name.to_sym == element.to_sym }
58
+ if (match)
59
+ new_val = Class.class_eval(match.class_name)
60
+ else
61
+ logger.error "I give up, cannot determine what #{element} is in #{path.inspect}"
62
+ end
63
+ end
64
+ else
65
+ logger.error "Unknown previous type when trying to dereference a collection #{element} in #{path.inspect}"
66
+ end
67
+ else
68
+ logger.error "Unable to determine prior element for #{element} in #{path.inspect}"
69
+ end
70
+ elsif previous
71
+ # call to the class / object in the previous statement
72
+ if (['find','all','first','last'].include?(element))
73
+ # then expect to receive an instance of the previous type
74
+ new_val = previous
75
+ end
76
+ end
77
+ previous = new_val
78
+ new_val
79
+ }
80
+ path.last
81
+ end
82
+
83
+ def logger
84
+ Rails.logger
85
+ end
86
+ end
@@ -0,0 +1,20 @@
1
+ class String
2
+ def stratagem_strip_erb
3
+ self.gsub(/^[<%=]+/, '').gsub(/[-%>]+$/,'').strip
4
+ end
5
+
6
+ def stratagem_contains_token?(token)
7
+ match = false
8
+ [
9
+ Regexp.compile("^#{token}$", true),
10
+ Regexp.compile("^#{token}[^A-Za-z0-9]", true),
11
+ Regexp.compile("[^A-Za-z0-9]#{token}$", true),
12
+ ].each do |regex|
13
+ if (regex.match(self))
14
+ match = true
15
+ break
16
+ end
17
+ end
18
+ match
19
+ end
20
+ end
@@ -0,0 +1,6 @@
1
+ require 'stratagem/extensions/red_parse'
2
+ require 'stratagem/extensions/class'
3
+ require 'stratagem/extensions/string'
4
+ require 'stratagem/extensions/hash'
5
+ require 'stratagem/extensions/object'
6
+ require 'stratagem/extensions/module'
@@ -0,0 +1,10 @@
1
+ class ActionController::Request
2
+ alias_method :rails_parameters, :parameters
3
+ undef_method :parameters
4
+
5
+ def parameters
6
+ params = rails_parameters
7
+ params.enable_auditing
8
+ params
9
+ end
10
+ end
@@ -0,0 +1,12 @@
1
+ module ActionMailer
2
+ class Base
3
+ def create!(method_name, *parameters)
4
+ puts "Skipping action mailer #{method_name}, #{parameters.inspect}"
5
+ end
6
+
7
+ def deliver!(mail = @mail)
8
+ puts "Skipping delivery in action mailer"
9
+ end
10
+ end
11
+ end
12
+
@@ -0,0 +1,5 @@
1
+ module Stratagem::ApplicationExtensions::Controllers; end
2
+
3
+ require 'stratagem/framework_extensions/controllers/action_controller'
4
+ require 'stratagem/framework_extensions/controllers/action_mailer'
5
+
@@ -0,0 +1,7 @@
1
+ module Stratagem::ApplicationExtensions::Models::Adapters::ActiveModel
2
+ class Detect < Stratagem::ApplicationExtensions::Models::Detect
3
+ def self.supports?(model)
4
+ model.ancestors.include?(ActiveRecord::Base)
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,35 @@
1
+ class ActiveRecord::Base
2
+ class << self
3
+ def removed_methods=(methods)
4
+ @@removed_methods = methods
5
+ end
6
+
7
+ def removed_methods
8
+ @@removed_methods
9
+ end
10
+
11
+ def removed_validators=(validators)
12
+ @@removed_validators = validators
13
+ end
14
+ end
15
+
16
+ Stratagem::ApplicationExtensions::Models::Annotations.configure(self)
17
+
18
+ end
19
+
20
+ module ActiveRecord::Validations::ClassMethods
21
+ @@removed_validators = []
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
+ end
30
+ end
31
+
32
+ def removed_validators
33
+ @@removed_validators
34
+ end
35
+ end