stratagem 0.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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,157 @@
1
+ # Note that an exception may be raised when a Gem is missing
2
+ # and not configured in environment.rb. Check for this case
3
+ # when loading classes
4
+ # Stratagem::Model
5
+
6
+ require 'set'
7
+ require 'singleton'
8
+
9
+ module Stratagem::Model
10
+ # container for application
11
+ class Application
12
+ include Singleton
13
+
14
+ attr_accessor :crawler
15
+ attr_reader :models, :controllers, :routes, :views, :static_files, :gems, :plugins
16
+
17
+ def initialize
18
+ log "initializing application model"
19
+ @models = ComponentContainer.new self
20
+ @controllers = ComponentContainer.new self
21
+ @routes = RouteContainer.new self
22
+ @views = ComponentContainer.new self
23
+ @static_files = ComponentContainer.new self
24
+ @gems = GemContainer.new self
25
+ @plugins = PluginContainer.new self
26
+ end
27
+
28
+ def log(msg)
29
+ Stratagem.logger.debug(msg)
30
+ end
31
+
32
+ def export
33
+ puts "exporting site model"
34
+ p crawler.export
35
+ puts "done."
36
+ h = {
37
+ :rails_version => rails_version,
38
+ :models => @models.export,
39
+ :controllers => @controllers.export,
40
+ :routes => @routes.export,
41
+ :views => @views.export,
42
+ :gems => @gems.export,
43
+ :plugins => @plugins.export,
44
+ :site_model => crawler.export,
45
+ :references => []
46
+ }
47
+ h
48
+ end
49
+
50
+ def rails_version
51
+ Rails.stratagem_rails_version
52
+ end
53
+ end
54
+
55
+ protected
56
+
57
+ class GemContainer
58
+ include Enumerable
59
+
60
+ def initialize(app_model)
61
+ @app_model = app_model
62
+ @gems = Gem.loaded_specs
63
+ end
64
+
65
+ def names
66
+ @gems.map {|g| g[0] }
67
+ end
68
+
69
+ def export(options=nil)
70
+ @gems.map {|g|
71
+ name, spec = g
72
+ [name, {:version => spec.version.version}]
73
+ }
74
+ end
75
+
76
+ def each
77
+ @gems.each {|spec| yield spec }
78
+ end
79
+ end
80
+
81
+ class ComponentContainer
82
+ include Enumerable
83
+
84
+ attr_reader :invalid, :missing, :parse_trees, :components, :errors
85
+
86
+ def initialize(app_model)
87
+ @app_model = app_model
88
+ @components = Set.new()
89
+ @parse_trees = {}
90
+ @invalid = []
91
+ @missing = {}
92
+ end
93
+
94
+ def export(options=nil)
95
+ {
96
+ :components => @components.to_a.map {|c| c.export }.compact,
97
+ :invalid => @invalid.map {|c| c.export }.compact
98
+ }
99
+ end
100
+
101
+ def find
102
+ @components.find{|component| yield component }
103
+ end
104
+
105
+ def size
106
+ @components.size
107
+ end
108
+
109
+ def -(other)
110
+ @components-other
111
+ end
112
+
113
+ def each
114
+ @components.each {|e| yield e }
115
+ end
116
+
117
+ def << (component)
118
+ if (component.kind_of?(Array))
119
+ component.each {|e|
120
+ @components << e
121
+ e.app_model = @app_model if e.methods_include?(:app_model=)
122
+ }
123
+ elsif (component.kind_of?(Exception))
124
+ errors << component
125
+ else
126
+ @components << component
127
+ component.app_model = @app_model if component.methods_include?(:app_model=)
128
+ end
129
+ end
130
+ end
131
+
132
+ class RouteContainer < ComponentContainer
133
+ def recognize(page, method=nil)
134
+ path = nil
135
+ if (page.kind_of?(Stratagem::Crawler::Page))
136
+ method = page.method
137
+ path = page.path
138
+ else
139
+ path = page
140
+ end
141
+ #ActionController::Routing::Routes.recognize_path('http://www.example.com/user_sessions/new', {:method => :get})
142
+ route = ActionController::Routing::Routes.routes.find {|r| r.recognize(path, {:method => method}) }
143
+ self.find {|r| r.route == route }
144
+ end
145
+ end
146
+
147
+ class PluginContainer < ComponentContainer
148
+ def names
149
+ components.map {|plugin| plugin.name }
150
+ end
151
+
152
+ def export(options=nil)
153
+ names
154
+ end
155
+ end
156
+ end
157
+
@@ -0,0 +1,55 @@
1
+ module Stratagem::Model::Component
2
+ class Base
3
+ include Stratagem::Model::ParseUtil
4
+
5
+ attr_reader :path, :source, :parse_tree, :klass
6
+ attr_accessor :app_model
7
+
8
+ def initialize(path, parse_tree, klass)
9
+ @path = path
10
+ @parse_tree = parse_tree
11
+ @klass = klass
12
+ end
13
+
14
+ def logger
15
+ Stratagem.logger
16
+ end
17
+
18
+ def self.logger
19
+ Stratagem.logger
20
+ end
21
+
22
+ def name
23
+ classname = @klass ? @klass.name : self.class.name.gsub(/.*[^A-Z0-9a-z]/, '')
24
+ "#{path}$#{classname}"
25
+ end
26
+
27
+ # loads all classes contained within a given filename
28
+ def self.load_all(path)
29
+ if (path =~ /\.rb$/)
30
+ source = File.read(path)
31
+ begin
32
+ parse_tree = RedParse.new(source).parse
33
+ Stratagem::Model::ParseUtil.find_classes(parse_tree).map {|klass|
34
+ self.new(path, parse_tree, klass)
35
+ }
36
+ rescue
37
+ puts $!.message
38
+ logger.fatal "Unable to load parse tree for #{path}"
39
+ []
40
+ end
41
+ end
42
+ end
43
+
44
+ def ==(other)
45
+ if (other.kind_of?(String))
46
+ self.path == other
47
+ elsif (other.kind_of?(self.class))
48
+ self.path == other.path
49
+ else
50
+ raise "unknown comparison to #{other.class.name}"
51
+ end
52
+ end
53
+
54
+ end
55
+ end
@@ -0,0 +1,118 @@
1
+ require 'set'
2
+
3
+ module Stratagem::Model::Component
4
+ class Action
5
+ def initialize(controller, name, method)
6
+ @name = name
7
+ @method = method # :put, :get, :post, :delete
8
+ @models_rendered = {} # model => [MethodInvocation]
9
+ end
10
+
11
+ def models_read
12
+ models(ActiveRecord::Base.stratagem.read_invocations)
13
+ end
14
+
15
+ def models_modified
16
+ models(ActiveRecord::Base.stratagem.write_invocations)
17
+ end
18
+
19
+ def models(invocations)
20
+ invocations.values.select {|invocation|
21
+ (invocation.controller_path == controller.path) &&
22
+ (invocation.controller_action == self.name)
23
+ }.map {|invocation|
24
+ invocation.model_class
25
+ }.uniq
26
+ end
27
+
28
+ end
29
+
30
+ class Controller < Base
31
+ attr_reader :clazz, :actions
32
+ attr_accessor :invalid_routes # named routes linked to the controller that are invalid
33
+
34
+ def initialize(*args)
35
+ super(*args)
36
+ @invalid_routes = {}
37
+ @actions = []
38
+ end
39
+
40
+ def add_routable_action(name, method)
41
+ @actions << Action.new(self, name, method)
42
+ end
43
+
44
+ def export
45
+ {
46
+ :external_id => self.object_id,
47
+ :type => :controller,
48
+ :path => @path.gsub(RAILS_ROOT+'/', ''),
49
+ :class_name => @klass.name,
50
+ :invalid_routes => @invalid_routes
51
+ }
52
+ end
53
+
54
+ # returns a list of references that create or update the specified model.
55
+ # see deletes? for destruction of model
56
+ def modifies(model)
57
+ # @modifies ||= {}
58
+ # @modifies[model] ||= begin
59
+ # outline = {} # method keys, value is hash of variables and values
60
+ # current_method = nil
61
+ # references = Set.new
62
+ #
63
+ # # return [] unless ((model.klass == WineFollow) && (self.klass == FollowsController))
64
+ #
65
+ # self.parse_tree.walk {|parent,i,subi,node|
66
+ # case node
67
+ # when RedParse::MethodNode #... do something with method calls
68
+ # current_method = node.name
69
+ # outline[current_method] = {}
70
+ # # puts "CURRENTMETHOD: #{current_method}"
71
+ # when RedParse::AssignNode
72
+ # if (node.left.kind_of?(RedParse::VarNode))
73
+ # begin
74
+ # # puts "assigning:#{node.left.name} -> #{node.right.dereference}"
75
+ # deref = node.right.dereference
76
+ # ((outline[current_method][node.left.name] ||= []) << deref) if current_method && deref
77
+ # rescue
78
+ # puts $!.message
79
+ # puts $!.backtrace
80
+ # logger.error("Cannot dereference node #{node.right.to_s}")
81
+ # end
82
+ # end
83
+ # when RedParse::CallNode
84
+ # ['update','create','new'].each {|m|
85
+ # # then this is a crud operation (excluding destroy)
86
+ # if (node.name.include?(m))
87
+ # if (node.talking_about? model)
88
+ # references << create_reference(node, current_method, model)
89
+ # break
90
+ # elsif (node.receiver && node.receiver.methods_include?(:name) && outline[current_method])
91
+ # if ((outline[current_method][node.receiver.name] || []).include?(model.klass))
92
+ # references << create_reference(node, current_method, model)
93
+ # break
94
+ # end
95
+ # end
96
+ # end
97
+ # }
98
+ # end
99
+ # node
100
+ # }
101
+ # references.to_a
102
+ # end
103
+ []
104
+ end
105
+
106
+ private
107
+
108
+ def create_reference(node, method, model)
109
+ Reference.new(
110
+ :from_class => self.klass,
111
+ :to_class => model.klass,
112
+ :method => method,
113
+ :line_number => node.linerange.first,
114
+ :reference_type => :write
115
+ )
116
+ end
117
+ end
118
+ end
@@ -0,0 +1,170 @@
1
+ module Stratagem::Model::Component
2
+ class Model < Base
3
+ attr_reader :model_attributes # database attributes that the model contains
4
+ attr_reader :model_assignable_attributes # fields / methods that can be manipulated in Model.new(..)
5
+ attr_reader :model_internal_attributes
6
+ attr_reader :model_accessible_attributes
7
+ attr_accessor :model_referenced_by # other classes / libraries that reference this model
8
+
9
+ ModificationMethods = ['update','create','new']
10
+
11
+ def initialize(*args)
12
+ super(*args)
13
+ load_attributes
14
+ @model_assignable_attributes = find_assignable_attributes
15
+ @model_instance_methods = self.klass.instance_methods
16
+ end
17
+
18
+ def stratagem?
19
+ klass.methods_include?(:stratagem)
20
+ end
21
+
22
+ # iterate model's associations to see if there's an association with the specific
23
+ # name and class. This is used as an aproximation to determine whether or
24
+ # not a node in the parse tree could be talking about a specific relationship
25
+ def association_match?(association_name, desired_model)
26
+ @association_matches ||= {}
27
+ @association_matches[association_name+"_"+desired_model.klass.name] ||= begin
28
+ klass.stratagem.relations.select {|relation|
29
+ (relation.name.to_sym == association_name.to_sym) && (relation.klass == desired_model.klass)
30
+ }.map {|relation|
31
+ relation.klass.name
32
+ }.first
33
+ rescue
34
+ Rails.logger.error("unable to lookup associations on #{self.klass.name} not active record model?")
35
+ Rails.logger.error($!)
36
+ false
37
+ end
38
+ @association_matches[association_name+"_"+desired_model.klass.name]
39
+ end
40
+
41
+ def load_attributes
42
+ @model_attributes = {}
43
+ if (stratagem?)
44
+ object = klass.new # used to look up metadata
45
+ object.stratagem.attribute_names.each {|attribute|
46
+ @model_attributes[attribute.to_sym] = object.stratagem.attribute_type(attribute.to_sym)
47
+ }
48
+ @model_foreign_keys = object.stratagem.foreign_keys
49
+ @model_internal_attributes = object.stratagem.internal_attributes
50
+ @model_accessible_attributes = object.stratagem.attribute_names - object.stratagem.unaccessible_attributes
51
+ end
52
+ end
53
+
54
+ # TODO - refactor into model persistence strategy
55
+ def find_assignable_attributes
56
+ assignable_attributes = []
57
+
58
+ # Using instance methods allows us to check for functions that would be mass assignable
59
+ # in addition to Active Record attributes
60
+ begin
61
+ if (stratagem?)
62
+ object = klass.new # used to look up metadata
63
+ if (object)
64
+ methods = nil
65
+ if (klass.stratagem.unaccessible_attributes)
66
+ assignable_attributes = (klass.stratagem.attribute_names - klass.stratagem.unaccessible_attributes).to_a
67
+ else
68
+ methods = klass.instance_methods + object.stratagem.attribute_names
69
+ methods.each {|method|
70
+ param_name = method.to_s.gsub('=','').to_sym
71
+ val = rand(100)
72
+ params = { param_name => val }
73
+ begin
74
+ instance = klass.new(params)
75
+ assignable_attributes << param_name.to_sym
76
+ rescue ActiveRecord::UnknownAttributeError
77
+ # the attribute is not mass assignable
78
+ rescue
79
+ # the function was called but an error was raised
80
+ assignable_attributes << param_name.to_sym
81
+ end
82
+ }
83
+ end
84
+ end
85
+ assignable_attributes.uniq
86
+ end
87
+ rescue
88
+ puts "Unable to analyze model #{klass.name}"
89
+ puts $!.message
90
+ puts $!.backtrace
91
+ # raise $!
92
+ []
93
+ end
94
+ end
95
+
96
+ # References to the find and find_x methods on the model
97
+ def references_to_finders()
98
+ references = []
99
+ method = nil
100
+ app_model.controllers.each {|controller|
101
+ controller.parse_tree.walk {|parent,i,subi,node|
102
+ case node
103
+ when RedParse::MethodNode
104
+ method = node
105
+ when RedParse::CallNode
106
+ if (!(parent.kind_of?(RedParse::AssignNode)) && (node.receiver) && (node.receiver.to_s == klass.name))
107
+ references << ControllerModelReference.new(controller, method.name, node.name, node)
108
+ end
109
+ end
110
+
111
+ case parent
112
+ when RedParse::AssignNode
113
+ # p parent
114
+ begin
115
+ if (node.kind_of?(RedParse::CallNode) && (node.receiver) && (node.receiver.name == klass.name))
116
+ references << ControllerModelReference.new(controller, method.name, node.name, node)
117
+ end
118
+ rescue
119
+ puts $!.message
120
+ puts $!.backtrace
121
+ # p parent
122
+ end
123
+ end
124
+ true
125
+ }
126
+ }
127
+ references
128
+ end
129
+
130
+ def export
131
+ adapters = stratagem? ? klass.stratagem.callbacks.map {|c| c.class.name } : []
132
+ {
133
+ :type => :model,
134
+ :path => @path.gsub(RAILS_ROOT+'/', ''),
135
+ :class_name => @klass.name,
136
+ :superclass => @klass.superclass.name,
137
+ :included_modules => @klass.included_modules.map {|m| m.name},
138
+ :attributes => @model_attributes,
139
+ :foreign_keys => @model_foreign_keys,
140
+ :assignable_attributes => @model_assignable_attributes,
141
+ :internal_attributes => @model_internal_attributes,
142
+ :accessible_attributes => @model_accessible_attributes,
143
+ :whitelists_attributes => stratagem? ? @klass.stratagem.whitelists_attributes? : nil,
144
+ :blacklists_attributes => stratagem? ? @klass.stratagem.blacklists_attributes? : nil,
145
+ :instance_methods => @model_instance_methods,
146
+ :referenced_by => @model_referenced_by.map {|r| r.export },
147
+ :relations => relations.map {|r| r.export },
148
+ :adapters => adapters
149
+ }
150
+ end
151
+
152
+ private
153
+
154
+ def relations
155
+ if (stratagem?)
156
+ @relations ||= klass.stratagem.relations.map {|relation|
157
+ Reference.new(:reference_type => relation.macro, :from_class => self.klass, :to_class => relation.klass)
158
+ }
159
+ else
160
+ []
161
+ end
162
+ end
163
+
164
+ def assignable(object, assignable_attributes, attribute)
165
+ column = object.column_for_attribute(attribute)
166
+ assignable_attributes[attribute] = column ? column.type : nil
167
+ end
168
+
169
+ end
170
+ end
@@ -0,0 +1,30 @@
1
+ module Stratagem::Model::Component
2
+ class Reference
3
+ attr_accessor :reference_type # :read, :write
4
+ attr_accessor :from_class, :to_class
5
+ attr_accessor :line_number
6
+ attr_accessor :method
7
+
8
+ Vars = [:reference_type, :from_class, :to_class, :line_number, :method]
9
+
10
+ def initialize(args={})
11
+ args.each {|key,val| self.send("#{key}=", val) }
12
+ end
13
+
14
+ def ==(other)
15
+ Vars.each do |attribute|
16
+ self.send(attribute) == other.send(attribute)
17
+ end
18
+ end
19
+
20
+ def export
21
+ h = {}
22
+ Vars.each do |key|
23
+ h[key.to_s] = self.send(key).to_s
24
+ end
25
+ h[:from_class.to_s] = from_class.name
26
+ h[:to_class.to_s] = to_class.name
27
+ h
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,53 @@
1
+ module Stratagem::Model::Component
2
+ class Route < Base
3
+ attr_reader :route
4
+
5
+ def initialize(route)
6
+ @route = route
7
+ end
8
+
9
+ def controller
10
+ if (route.requirements[:controller])
11
+ begin
12
+ controller_class = "#{route.requirements[:controller].to_s.camelize}Controller".constantize
13
+ Stratagem::Model::Application.instance.controllers.find {|c| c.klass == controller_class }
14
+ rescue
15
+ puts "unable to determine controller #{route.requirements[:controller]}"
16
+ puts $!.message
17
+ nil
18
+ end
19
+ else
20
+ nil
21
+ end
22
+ end
23
+
24
+ def action
25
+ route.requirements[:action] ? route.requirements[:action].to_sym : nil
26
+ end
27
+
28
+ def ==(other)
29
+ if (other.kind_of?(ActionController::Routing::Route))
30
+ self.route == other
31
+ elsif (other.kind_of?(Stratagem::Model::Component::Route))
32
+ self.route.requirements == other.route.requirements && self.route.segments == other.route.segments
33
+ else
34
+ raise "unknown comparison to #{other.class.name}"
35
+ end
36
+ end
37
+
38
+ def export
39
+ p @route.requirements
40
+ p action
41
+ puts "--"
42
+ {
43
+ :external_id => self.object_id,
44
+ :type => :route,
45
+ :path => nil,
46
+ :requirements => @route.requirements,
47
+ :segments => @route.segments.map {|s| s.to_s },
48
+ :controller_external_id => controller ? controller.object_id : nil,
49
+ :action => action,
50
+ }
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,18 @@
1
+ module Stratagem::Model::Component
2
+ class StaticFile < Base
3
+
4
+ def initialize(public_path)
5
+ @path = public_path
6
+ end
7
+
8
+ def read
9
+ File.read(full_path)
10
+ end
11
+
12
+ def full_path
13
+ File.join(RAILS_ROOT, 'public', path)
14
+ end
15
+ end
16
+
17
+ end
18
+