stratagem 0.2.3 → 0.2.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. data/Manifest +16 -6
  2. data/Rakefile +8 -1
  3. data/lib/generators/stratagem/install/install_base.rb +13 -3
  4. data/lib/generators/stratagem/install/install_generator.rb +1 -1
  5. data/lib/stratagem.rb +42 -18
  6. data/lib/stratagem/authentication.rb +2 -5
  7. data/lib/stratagem/auto_mock.rb +1 -0
  8. data/lib/stratagem/auto_mock/aquifer.rb +49 -26
  9. data/lib/stratagem/auto_mock/factory.rb +1 -6
  10. data/lib/stratagem/auto_mock/user_loader.rb +38 -0
  11. data/lib/stratagem/client.rb +15 -4
  12. data/lib/stratagem/configuration/auth_auth.rb +19 -0
  13. data/lib/stratagem/configuration/core.rb +20 -0
  14. data/lib/stratagem/crawler/authentication.rb +17 -12
  15. data/lib/stratagem/crawler/authentication/automated.rb +40 -0
  16. data/lib/stratagem/crawler/authentication/base.rb +140 -0
  17. data/lib/stratagem/crawler/authentication/configured.rb +27 -0
  18. data/lib/stratagem/crawler/parameter_resolver.rb +12 -8
  19. data/lib/stratagem/crawler/route_invoker.rb +10 -13
  20. data/lib/stratagem/crawler/session.rb +14 -2
  21. data/lib/stratagem/crawler/site_model.rb +4 -173
  22. data/lib/stratagem/crawler/site_model/edge.rb +20 -0
  23. data/lib/stratagem/crawler/site_model/page.rb +121 -0
  24. data/lib/stratagem/crawler/site_model/page_set.rb +58 -0
  25. data/lib/stratagem/instrumentation/models.rb +3 -14
  26. data/lib/stratagem/instrumentation/models/annotations.rb +39 -5
  27. data/lib/stratagem/instrumentation/models/authentication.rb +0 -1
  28. data/lib/stratagem/instrumentation/models/authentication/authlogic/detect.rb +1 -0
  29. data/lib/stratagem/instrumentation/models/authentication/devise/detect.rb +1 -1
  30. data/lib/stratagem/instrumentation/models/authentication/devise/instrumentation.rb +0 -4
  31. data/lib/stratagem/instrumentation/models/metadata.rb +23 -1
  32. data/lib/stratagem/instrumentation/models/persistence.rb +3 -4
  33. data/lib/stratagem/instrumentation/models/persistence/active_record/metadata.rb +2 -2
  34. data/lib/stratagem/interface/browser.rb +9 -3
  35. data/lib/stratagem/interface/public/javascripts/stratagem.js +14 -12
  36. data/lib/stratagem/interface/views/index.haml +3 -3
  37. data/lib/stratagem/logger.rb +28 -2
  38. data/lib/stratagem/model.rb +6 -0
  39. data/lib/stratagem/model/application.rb +21 -134
  40. data/lib/stratagem/model/components/base.rb +1 -4
  41. data/lib/stratagem/model/components/controller.rb +1 -2
  42. data/lib/stratagem/model/components/model.rb +15 -15
  43. data/lib/stratagem/model/components/route.rb +3 -2
  44. data/lib/stratagem/model/components/view.rb +0 -1
  45. data/lib/stratagem/model/containers/base.rb +60 -0
  46. data/lib/stratagem/model/containers/gem.rb +25 -0
  47. data/lib/stratagem/model/containers/plugin.rb +11 -0
  48. data/lib/stratagem/model/containers/route.rb +19 -0
  49. data/lib/stratagem/model/parse_util.rb +3 -3
  50. data/lib/stratagem/model_builder.rb +1 -4
  51. data/lib/stratagem/rack_hack.rb +15 -0
  52. data/lib/stratagem/site_crawler.rb +5 -4
  53. data/lib/stratagem/snapshot.rb +5 -7
  54. data/spec/stratagem/configuration_spec.rb +32 -0
  55. data/stratagem.gemspec +5 -8
  56. data/templates/install/environments/stratagem.rb.erb +31 -2
  57. data/templates/install/script/stratagem +16 -0
  58. data/templates/install/tasks/stratagem.rake +2 -2
  59. metadata +36 -65
  60. data/bin/stratagem +0 -58
  61. data/lib/stratagem/scan.rb +0 -19
  62. data/lib/stratagem/scan/checks/email_address.rb +0 -15
  63. data/lib/stratagem/scan/checks/error_pages.rb +0 -25
  64. data/lib/stratagem/scan/result.rb +0 -45
  65. data/lib/stratagem/scanner.rb +0 -32
data/Manifest CHANGED
@@ -1,7 +1,6 @@
1
1
  LICENSE
2
2
  Manifest
3
3
  Rakefile
4
- bin/stratagem
5
4
  generators/stratagem/stratagem_generator.rb
6
5
  init.rb
7
6
  lib/bootstrap.rb
@@ -13,6 +12,7 @@ lib/stratagem/authentication.rb
13
12
  lib/stratagem/auto_mock.rb
14
13
  lib/stratagem/auto_mock/aquifer.rb
15
14
  lib/stratagem/auto_mock/factory.rb
15
+ lib/stratagem/auto_mock/user_loader.rb
16
16
  lib/stratagem/auto_mock/value_generator.rb
17
17
  lib/stratagem/blocker.rb
18
18
  lib/stratagem/client.rb
@@ -21,14 +21,22 @@ lib/stratagem/commands.rb
21
21
  lib/stratagem/commands/analyze.rb
22
22
  lib/stratagem/commands/base.rb
23
23
  lib/stratagem/commands/devel_mock.rb
24
+ lib/stratagem/configuration/auth_auth.rb
25
+ lib/stratagem/configuration/core.rb
24
26
  lib/stratagem/crawler.rb
25
27
  lib/stratagem/crawler/authentication.rb
28
+ lib/stratagem/crawler/authentication/automated.rb
29
+ lib/stratagem/crawler/authentication/base.rb
30
+ lib/stratagem/crawler/authentication/configured.rb
26
31
  lib/stratagem/crawler/form.rb
27
32
  lib/stratagem/crawler/html_utils.rb
28
33
  lib/stratagem/crawler/parameter_resolver.rb
29
34
  lib/stratagem/crawler/route_invoker.rb
30
35
  lib/stratagem/crawler/session.rb
31
36
  lib/stratagem/crawler/site_model.rb
37
+ lib/stratagem/crawler/site_model/edge.rb
38
+ lib/stratagem/crawler/site_model/page.rb
39
+ lib/stratagem/crawler/site_model/page_set.rb
32
40
  lib/stratagem/crawler/trace_utils.rb
33
41
  lib/stratagem/extensions.rb
34
42
  lib/stratagem/extensions/class.rb
@@ -102,16 +110,18 @@ lib/stratagem/model/components/reference.rb
102
110
  lib/stratagem/model/components/route.rb
103
111
  lib/stratagem/model/components/static_file.rb
104
112
  lib/stratagem/model/components/view.rb
113
+ lib/stratagem/model/containers/base.rb
114
+ lib/stratagem/model/containers/gem.rb
115
+ lib/stratagem/model/containers/plugin.rb
116
+ lib/stratagem/model/containers/route.rb
105
117
  lib/stratagem/model/parse_util.rb
106
118
  lib/stratagem/model_builder.rb
119
+ lib/stratagem/rack_hack.rb
107
120
  lib/stratagem/recipes/deploy.rb
108
- lib/stratagem/scan.rb
109
121
  lib/stratagem/scan/checks/capistrano/secure_deploy.rb
110
- lib/stratagem/scan/checks/email_address.rb
111
- lib/stratagem/scan/checks/error_pages.rb
112
- lib/stratagem/scan/result.rb
113
- lib/stratagem/scanner.rb
114
122
  lib/stratagem/site_crawler.rb
115
123
  lib/stratagem/snapshot.rb
124
+ spec/stratagem/configuration_spec.rb
116
125
  templates/install/environments/stratagem.rb.erb
126
+ templates/install/script/stratagem
117
127
  templates/install/tasks/stratagem.rake
data/Rakefile CHANGED
@@ -1,8 +1,14 @@
1
1
  require 'rubygems'
2
2
  require 'rake'
3
3
  require 'echoe'
4
+ require "rspec"
5
+ require "rspec/core/rake_task"
4
6
 
5
- Echoe.new('stratagem', '0.2.3') do |p|
7
+ Rspec::Core::RakeTask.new(:spec) do |spec|
8
+ spec.pattern = "spec/**/*_spec.rb"
9
+ end
10
+
11
+ Echoe.new('stratagem', '0.2.4') do |p|
6
12
  p.description = "Intuitive security analysis for your Rails applications"
7
13
  p.url = "http://www.stratagemapp.com"
8
14
  p.author = "Charles Grimes"
@@ -15,3 +21,4 @@ Echoe.new('stratagem', '0.2.3') do |p|
15
21
  end
16
22
 
17
23
  Dir["#{File.dirname(__FILE__)}/tasks/*.rake"].sort.each { |ext| load ext }
24
+
@@ -2,20 +2,30 @@ module Stratagem
2
2
  module Generators
3
3
  module InstallBase
4
4
  def create_all(m=self)
5
+ create_scripts(m)
5
6
  create_config(m)
6
7
  create_tasks(m)
7
8
  create_database(m)
8
9
  end
9
10
 
10
- def create_config(m = self)
11
+ def create_scripts(m)
12
+ m.template('script/stratagem', 'script/stratagem', options)
13
+ begin
14
+ chmod 'script/stratagem', 0755
15
+ rescue
16
+ puts "ERROR: #{$!.message}"
17
+ end
18
+ end
19
+
20
+ def create_config(m)
11
21
  m.template 'environments/stratagem.rb.erb', 'config/environments/stratagem.rb'
12
22
  end
13
23
 
14
- def create_tasks(m = self)
24
+ def create_tasks(m)
15
25
  m.template 'tasks/stratagem.rake', 'lib/tasks/stratagem.rake'
16
26
  end
17
27
 
18
- def create_database(m = self)
28
+ def create_database(m)
19
29
  append_yml(m, 'mongoid.yml', 'database.yml', 'workling.yml')
20
30
  end
21
31
 
@@ -5,7 +5,7 @@ module Stratagem
5
5
  include Stratagem::Generators::InstallBase
6
6
 
7
7
  def generate
8
- create_all
8
+ create_all(self)
9
9
  end
10
10
 
11
11
  def self.gem_root
@@ -1,3 +1,6 @@
1
+ require 'stratagem/configuration/core'
2
+ require 'stratagem/configuration/auth_auth'
3
+
1
4
  class StratagemError < RuntimeError
2
5
  attr_accessor :target
3
6
 
@@ -9,10 +12,25 @@ end
9
12
 
10
13
  module Stratagem
11
14
  class << self
15
+ def configure(&block)
16
+ @@configuration = Configuration::Core.new
17
+ block.call(@@configuration) if block
18
+ @@configuration
19
+ end
20
+
21
+ def configuration
22
+ @@configuration
23
+ end
24
+
25
+ def prescan(&block)
26
+ @@prescan = block if block
27
+ end
28
+
12
29
  def load_dependencies
13
30
  require 'haml'
14
31
  require 'launchy'
15
32
  require 'redparse'
33
+ require 'stratagem/rack_hack'
16
34
  require 'stratagem/blocker'
17
35
  require 'stratagem/logger'
18
36
  require 'stratagem/extensions'
@@ -25,8 +43,6 @@ module Stratagem
25
43
  require 'stratagem/client'
26
44
  require 'stratagem/command'
27
45
  require 'stratagem/model_builder'
28
- require 'stratagem/scanner'
29
- require 'stratagem/scan'
30
46
  require 'stratagem/crawler'
31
47
  require 'stratagem/site_crawler'
32
48
  require 'stratagem/snapshot'
@@ -36,25 +52,25 @@ module Stratagem
36
52
 
37
53
  def init
38
54
  load_dependencies
39
-
55
+
56
+ @@prescan = nil
40
57
  @@blocker = Blocker.new
41
58
  @@running = false
42
59
  @@session_id = Time.now.to_f.to_s # the interface uses this to determine which instance of the client it's talking to
43
60
  end
44
61
 
45
62
  def ssl?
46
- true
63
+ !local?
47
64
  end
48
65
 
49
66
  def domain
50
- 'stratagemapp.com'
51
- end
52
-
53
- def mocking?
54
- true
67
+ if local?
68
+ 'localhost:3000'
69
+ else
70
+ 'stratagemapp.com'
71
+ end
55
72
  end
56
73
 
57
-
58
74
  def rails_version
59
75
  @@rails_version ||= begin
60
76
  rails_version = Rails.version.split('.').map {|v| v.size > 1 ? 9 : v.to_i }
@@ -80,7 +96,6 @@ module Stratagem
80
96
  Stratagem::Logger.instance
81
97
  end
82
98
 
83
- # register an error that occurred during the lifecycle of the scanner
84
99
  def error(error)
85
100
  errors << error
86
101
  end
@@ -94,6 +109,7 @@ module Stratagem
94
109
  end
95
110
 
96
111
  def complete
112
+ Stratagem.logger.phase('complete')
97
113
  @@blocker.notify
98
114
  end
99
115
 
@@ -102,27 +118,35 @@ module Stratagem
102
118
  @@running = true
103
119
  Thread.new {
104
120
  begin
105
- # RubyProf.start
121
+ if (configuration.use_transactional_crawling)
122
+ ActiveRecord::Base.connection.increment_open_transactions
123
+ ActiveRecord::Base.connection.transaction_joinable = false
124
+ ActiveRecord::Base.connection.begin_db_transaction
125
+ end
106
126
 
127
+ prescan.call unless prescan.nil?
107
128
  authentication = Stratagem::Authentication.instance
108
129
  snapshot = Stratagem::Snapshot.create(authentication.project)
109
130
  Stratagem::Client.new(authentication).send(snapshot)
110
-
111
- # result = RubyProf.stop
112
- #
113
- # # Print a flat profile to text
114
- # printer = RubyProf::FlatPrinter.new(result)
115
- # printer.print(STDOUT, 0)
116
131
  rescue Exception
117
132
  puts $!.message
118
133
  puts $!.backtrace
119
134
  ensure
135
+ if (configuration.use_transactional_crawling)
136
+ ActiveRecord::Base.connection.decrement_open_transactions
137
+ ActiveRecord::Base.connection.rollback_db_transaction
138
+ end
139
+
120
140
  complete
121
141
  end
122
142
  }
123
143
  end
124
144
  end
125
145
 
146
+
147
+ def local?
148
+ ENV['local'] && ENV['local'] == 'true'
149
+ end
126
150
  end
127
151
 
128
152
  end
@@ -9,9 +9,8 @@ module Stratagem
9
9
 
10
10
  attr_reader :token, :project
11
11
 
12
- def store_credentials(account, token, project)
12
+ def store_credentials(token, project)
13
13
  File.open(FILENAME, 'w') do |f|
14
- f.puts account
15
14
  f.puts token
16
15
  f.puts project
17
16
  end
@@ -27,9 +26,8 @@ module Stratagem
27
26
  end
28
27
 
29
28
  def base_url
30
- subdomain = credentials ? credentials[:account] : 'www'
31
29
  protocol = Stratagem.ssl? ? 'https' : 'http'
32
- "#{protocol}://#{subdomain}.#{Stratagem.domain}"
30
+ "#{protocol}://#{Stratagem.domain}"
33
31
  end
34
32
 
35
33
  def project_url
@@ -51,7 +49,6 @@ module Stratagem
51
49
  credentials = nil
52
50
  File.open(FILENAME) do |f|
53
51
  credentials = {
54
- :account => f.readline.strip,
55
52
  :token => f.readline.strip,
56
53
  :project => f.readline.strip
57
54
  }
@@ -1,6 +1,7 @@
1
1
  module Stratagem::AutoMock
2
2
  end
3
3
 
4
+ require 'stratagem/auto_mock/user_loader'
4
5
  require 'stratagem/auto_mock/value_generator'
5
6
  require 'stratagem/auto_mock/factory'
6
7
  require 'stratagem/auto_mock/aquifer'
@@ -4,6 +4,7 @@ module Stratagem::AutoMock
4
4
  class Aquifer
5
5
  include Singleton
6
6
  include Factory
7
+ include UserLoader
7
8
 
8
9
  attr_accessor :application
9
10
 
@@ -14,7 +15,7 @@ module Stratagem::AutoMock
14
15
  end
15
16
 
16
17
  def clear
17
- if (Stratagem.mocking?)
18
+ if (Stratagem.configuration.use_automatic_mocking)
18
19
  objects = self.repo.values.inject([]) {|memo,obj| memo += obj.compact }
19
20
  i = 0
20
21
  while (objects.size > 0 && ((i+=1) < objects.size))
@@ -28,7 +29,7 @@ module Stratagem::AutoMock
28
29
  instance.delete
29
30
  rescue
30
31
  puts "Unable to delete object: #{instance.class.name} - #{$!.message}"
31
- puts $!.backtrace
32
+ Stratagem.logger.error($!)
32
33
  end
33
34
  end
34
35
  !instance.frozen?
@@ -71,23 +72,19 @@ module Stratagem::AutoMock
71
72
  end
72
73
 
73
74
  def load_existing_object_ids(klass)
74
- if (Stratagem.mocking?)
75
- # handle polymorphic objects (class may actually be a subclass of the klass parameter)
76
- klass.existing_instance_ids.each do |existing_id|
77
- if (existing_id.kind_of?(Fixnum))
78
- begin
79
- instance = klass.find(existing_id)
80
- (pre_existing_object_ids[instance.class] ||= []) << existing_id
81
- rescue
82
- puts "ERROR: instance id #{existing_id} of #{klass.name} could not be loaded"
83
- end
84
- else
85
- # an instance was loaded because the model has no id field
75
+ # handle polymorphic objects (class may actually be a subclass of the klass parameter)
76
+ klass.existing_instance_ids.each do |existing_id|
77
+ if (existing_id.kind_of?(Fixnum))
78
+ begin
79
+ instance = klass.find(existing_id)
86
80
  (pre_existing_object_ids[instance.class] ||= []) << existing_id
81
+ rescue
82
+ puts "ERROR: instance id #{existing_id} of #{klass.name} could not be loaded - #{$!.message}"
87
83
  end
84
+ else
85
+ # an instance was loaded because the model has no id field
86
+ (pre_existing_object_ids[instance.class] ||= []) << existing_id
88
87
  end
89
- else
90
- pre_existing_object_ids[klass] = []
91
88
  end
92
89
  end
93
90
 
@@ -99,10 +96,33 @@ module Stratagem::AutoMock
99
96
  end
100
97
  end
101
98
 
99
+ def fill_by_configuration(credentials, model_count=nil)
100
+ objects_by_class = {}
101
+
102
+ log "Loading users for #{credentials.size} sets of credentials"
103
+ credentials.each do |user_credentials|
104
+ log "\t#{user_credentials.authentication_parameters.inspect}"
105
+ user = load_user_from_configuration(user_credentials)
106
+ if (user)
107
+ log "Loaded credentials for user #{user.id}: #{user.stratagem.mock_attributes.inspect}"
108
+ user.stratagem.related_objects.slice(0,5).each do |object|
109
+ (objects_by_class[object.class] ||= []) << object
110
+ end
111
+ else
112
+ Stratagem.logger.fatal "Could not locate user with credentials: #{user_credentials.authentication_parameters.inspect}"
113
+ end
114
+ end
115
+
116
+ log "Loaded #{objects_by_class.keys.size} object types: #{objects_by_class.keys.inspect}"
102
117
 
103
- def fill(model_count=nil)
104
- Stratagem.logger.phase "mocking_models"
118
+ objects_by_class.each do |klass, objects|
119
+ puts "filling aquifer - class #{klass.name} has #{objects.size} instances"
120
+ repo[klass.name] = objects
121
+ end
122
+ self
123
+ end
105
124
 
125
+ def fill_by_automock(model_count=nil)
106
126
  # load the ids of existing models for each class
107
127
  application.models.each do |meta_model|
108
128
  next unless meta_model.stratagem?
@@ -110,10 +130,8 @@ module Stratagem::AutoMock
110
130
  end
111
131
 
112
132
  # mock instances of all models
113
- if (Stratagem.mocking?)
114
- application.models.each do |meta_model|
115
- mock_model(meta_model.klass, model_count) if (meta_model.stratagem?)
116
- end
133
+ application.models.each do |meta_model|
134
+ mock_model(meta_model.klass, model_count) if (meta_model.stratagem?)
117
135
  end
118
136
 
119
137
  # determine the new ids for each model
@@ -123,12 +141,16 @@ module Stratagem::AutoMock
123
141
 
124
142
  known_mocked_instances = mocked(meta_model.klass)
125
143
  new_ids = load_instance_ids(meta_model) - (pre_existing_object_ids[meta_model.klass] || [])
144
+
145
+ # limit the number of objects that the system will interact with
146
+ new_ids = new_ids.slice(0,200)
126
147
  repo[meta_model.klass.name] = new_ids.map {|id|
127
148
  if (id.kind_of?(Fixnum))
149
+ puts "loading instance #{id} of #{meta_model.klass.name}"
128
150
  begin
129
151
  known_mocked_instances.find {|i| i.id == id } || meta_model.klass.find(id)
130
152
  rescue
131
- puts "ERROR: #{$!.message}"
153
+ puts "FILL ERROR: #{$!.message}"
132
154
  nil
133
155
  end
134
156
  else
@@ -160,6 +182,10 @@ module Stratagem::AutoMock
160
182
  end
161
183
  end
162
184
 
185
+ def repo
186
+ mocked
187
+ end
188
+
163
189
  protected
164
190
 
165
191
  def instance_call(instance, method, *args)
@@ -174,8 +200,5 @@ module Stratagem::AutoMock
174
200
  end
175
201
 
176
202
 
177
- def repo
178
- mocked
179
- end
180
203
  end
181
204
  end
@@ -48,12 +48,10 @@ module Stratagem::AutoMock
48
48
  end
49
49
  end
50
50
  rescue Exception, ActiveRecord::ActiveRecordError
51
- # puts $!.class.name
52
- # puts $!.message
53
- # puts $!.backtrace
54
51
  e = MockError.new("Unexpected error mocking model #{model.name} - #{$!.message}")
55
52
  puts e.message
56
53
  e.target = $!
54
+ Stratagem.logger.error(e)
57
55
  # raise e
58
56
  end
59
57
 
@@ -168,11 +166,8 @@ module Stratagem::AutoMock
168
166
  valid = false
169
167
  end
170
168
  puts "\tERROR: could not correct errors in model" unless valid
171
- # puts $!.backtrace unless valid
172
169
  end
173
170
 
174
- # puts "\t#{object.stratagem.mock_attributes.inspect}" if (valid)
175
-
176
171
  valid
177
172
  end
178
173