stratagem 0.1.8 → 0.1.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. data/Manifest +16 -18
  2. data/Rakefile +3 -3
  3. data/bin/stratagem +54 -6
  4. data/generators/stratagem/stratagem_generator.rb +26 -0
  5. data/lib/generators/stratagem/install/USAGE +0 -0
  6. data/lib/generators/stratagem/install/install_base.rb +35 -0
  7. data/lib/generators/stratagem/install/install_generator.rb +24 -0
  8. data/lib/stratagem.rb +87 -57
  9. data/lib/stratagem/authentication.rb +2 -2
  10. data/lib/stratagem/auto_mock/aquifer.rb +6 -1
  11. data/lib/stratagem/auto_mock/factory.rb +2 -2
  12. data/lib/stratagem/client.rb +1 -1
  13. data/lib/stratagem/crawler.rb +2 -0
  14. data/lib/stratagem/crawler/authentication.rb +10 -9
  15. data/lib/stratagem/crawler/parameter_resolver.rb +83 -0
  16. data/lib/stratagem/crawler/route_invoker.rb +187 -0
  17. data/lib/stratagem/crawler/session.rb +23 -251
  18. data/lib/stratagem/crawler/site_model.rb +18 -16
  19. data/lib/stratagem/framework_extensions.rb +12 -1
  20. data/lib/stratagem/framework_extensions/method_invocation.rb +50 -0
  21. data/lib/stratagem/framework_extensions/models/adapters/active_model/detect.rb +1 -1
  22. data/lib/stratagem/framework_extensions/models/adapters/active_model/extensions.rb +20 -11
  23. data/lib/stratagem/framework_extensions/models/adapters/active_model/metadata.rb +7 -3
  24. data/lib/stratagem/framework_extensions/models/adapters/active_model/tracing.rb +11 -9
  25. data/lib/stratagem/framework_extensions/models/adapters/friendly_id/detect.rb +12 -0
  26. data/lib/stratagem/framework_extensions/models/adapters/friendly_id/extensions.rb +0 -0
  27. data/lib/stratagem/framework_extensions/models/adapters/friendly_id/metadata.rb +21 -0
  28. data/lib/stratagem/framework_extensions/models/adapters/friendly_id/tracing.rb +4 -0
  29. data/lib/stratagem/framework_extensions/models/annotations.rb +1 -24
  30. data/lib/stratagem/framework_extensions/models/tracing.rb +9 -3
  31. data/lib/stratagem/framework_extensions/rails.rb +0 -6
  32. data/lib/stratagem/framework_extensions/{controllers → rails2}/action_controller.rb +0 -0
  33. data/lib/stratagem/framework_extensions/{controllers → rails2}/action_mailer.rb +0 -0
  34. data/lib/stratagem/framework_extensions/rails3/parameters.rb +14 -0
  35. data/lib/stratagem/interface/browser.rb +3 -1
  36. data/lib/stratagem/model/application.rb +6 -6
  37. data/lib/stratagem/model/components/controller.rb +17 -63
  38. data/lib/stratagem/model/components/model.rb +33 -33
  39. data/lib/stratagem/model/components/reference.rb +8 -4
  40. data/lib/stratagem/model/components/route.rb +40 -14
  41. data/lib/stratagem/model/components/view.rb +1 -1
  42. data/lib/stratagem/model_builder.rb +71 -42
  43. data/lib/stratagem/site_crawler.rb +1 -1
  44. data/lib/stratagem/snapshot.rb +0 -1
  45. data/stratagem.gemspec +10 -7
  46. data/templates/install/environments/stratagem.rb.erb +16 -0
  47. data/templates/install/tasks/stratagem.rake +18 -0
  48. metadata +57 -40
  49. data/lib/stratagem/framework_extensions/controllers.rb +0 -5
  50. data/lib/stratagem/scan/checks/filter_parameter_logging.rb +0 -6
  51. data/lib/stratagem/scan/checks/mongo_mapper/base.rb +0 -19
  52. data/lib/stratagem/scan/checks/mongo_mapper/foreign_keys_exposed.rb +0 -32
  53. data/lib/stratagem/scan/checks/routes.rb +0 -16
  54. data/lib/tasks/_old_stratagem.rake +0 -99
  55. data/spec/model/component_spec.rb +0 -43
  56. data/spec/model/components/view_spec.rb +0 -43
  57. data/spec/model/test_spec.rb +0 -10
  58. data/spec/samples/404.html.erb +0 -30
  59. data/spec/samples/_form.html.erb +0 -8
  60. data/spec/samples/index.html.erb +0 -77
  61. data/spec/samples/sample_model.rb +0 -5
  62. data/spec/samples/signup.html.erb +0 -14
  63. data/spec/scan/checks/email_address_spec.rb +0 -24
  64. 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
- :type => type
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
- :method => method,
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 => response.request.parameters.to_json
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 = response.request.url
106
- @path = response.request.path
107
- @method = response.request.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/controllers'
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::ActiveModel
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
- module ActiveRecord::Validations::ClassMethods
20
+ class ActiveRecord::Base #Validations::ClassMethods
21
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
-
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::ActiveModel
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
- Stratagem::ApplicationExtensions::Models::Metadata::StratagemAssociation.new(a.name.to_sym, a.association_foreign_key.to_sym, a.klass, a.macro, a.options)
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::ActiveModel
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
- if (self.removed_methods.include?(method.to_sym))
25
+ method = method.to_sym
26
+ if (self.removed_methods.include?(method))
26
27
  # puts "read invocation: #{self.name} -> #{method} -> #{args.inspect}"
27
- stratagem.read_invocation(method, args) if (@@removed_finder_methods.include?(method))
28
- send("old_"+method.to_s, *args, &block)
29
- elsif (self.removed_validators.include?(method.to_sym))
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(/active_record\/base\.rb/)
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
@@ -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
@@ -0,0 +1,4 @@
1
+ module Stratagem::ApplicationExtensions::Models::Adapters::FriendlyId
2
+ module Tracing
3
+ end
4
+ 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
- path,action,line,trace,index = controller_trace(/active_record\/base\.rb/)
42
- invocation(method, args, read_invocations, :read) unless (action =~ /create/) || (action =~ /update/) || (action =~ /save/)
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/)
@@ -1,8 +1,2 @@
1
1
  module Rails
2
- def self.stratagem_rails_version
3
- rails_version = Rails.version.split('.')
4
- rails_version << 0 while rails_version.size < 3
5
- rails_version.pop while rails_version.size > 3
6
- rails_version.join.to_i
7
- end
8
2
  end
@@ -0,0 +1,14 @@
1
+ module ActionDispatch
2
+ module Http
3
+ module Parameters
4
+ alias_method :rails_parameters, :parameters
5
+ undef_method :parameters
6
+
7
+ def parameters
8
+ params = rails_parameters
9
+ params.enable_auditing
10
+ params
11
+ end
12
+ end
13
+ end
14
+ end
@@ -1,7 +1,9 @@
1
1
  require 'rubygems'
2
2
  require 'sinatra'
3
- require 'erb'
3
+ # require 'erb'
4
4
 
5
+ set :public, File.dirname(__FILE__) + '/public'
6
+ set :views, File.dirname(__FILE__) + '/views'
5
7
  set :run, false
6
8
  enable :sessions
7
9
  disable :logging
@@ -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
- p h
48
+ puts h.to_json
47
49
  h
48
50
  end
49
51
 
50
52
  def rails_version
51
- Rails.stratagem_rails_version
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=nil)
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
- #ActionController::Routing::Routes.recognize_path('http://www.example.com/user_sessions/new', {:method => :get})
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