stratagem 0.2.3 → 0.2.4
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.
- data/Manifest +16 -6
- data/Rakefile +8 -1
- data/lib/generators/stratagem/install/install_base.rb +13 -3
- data/lib/generators/stratagem/install/install_generator.rb +1 -1
- data/lib/stratagem.rb +42 -18
- data/lib/stratagem/authentication.rb +2 -5
- data/lib/stratagem/auto_mock.rb +1 -0
- data/lib/stratagem/auto_mock/aquifer.rb +49 -26
- data/lib/stratagem/auto_mock/factory.rb +1 -6
- data/lib/stratagem/auto_mock/user_loader.rb +38 -0
- data/lib/stratagem/client.rb +15 -4
- data/lib/stratagem/configuration/auth_auth.rb +19 -0
- data/lib/stratagem/configuration/core.rb +20 -0
- data/lib/stratagem/crawler/authentication.rb +17 -12
- data/lib/stratagem/crawler/authentication/automated.rb +40 -0
- data/lib/stratagem/crawler/authentication/base.rb +140 -0
- data/lib/stratagem/crawler/authentication/configured.rb +27 -0
- data/lib/stratagem/crawler/parameter_resolver.rb +12 -8
- data/lib/stratagem/crawler/route_invoker.rb +10 -13
- data/lib/stratagem/crawler/session.rb +14 -2
- data/lib/stratagem/crawler/site_model.rb +4 -173
- data/lib/stratagem/crawler/site_model/edge.rb +20 -0
- data/lib/stratagem/crawler/site_model/page.rb +121 -0
- data/lib/stratagem/crawler/site_model/page_set.rb +58 -0
- data/lib/stratagem/instrumentation/models.rb +3 -14
- data/lib/stratagem/instrumentation/models/annotations.rb +39 -5
- data/lib/stratagem/instrumentation/models/authentication.rb +0 -1
- data/lib/stratagem/instrumentation/models/authentication/authlogic/detect.rb +1 -0
- data/lib/stratagem/instrumentation/models/authentication/devise/detect.rb +1 -1
- data/lib/stratagem/instrumentation/models/authentication/devise/instrumentation.rb +0 -4
- data/lib/stratagem/instrumentation/models/metadata.rb +23 -1
- data/lib/stratagem/instrumentation/models/persistence.rb +3 -4
- data/lib/stratagem/instrumentation/models/persistence/active_record/metadata.rb +2 -2
- data/lib/stratagem/interface/browser.rb +9 -3
- data/lib/stratagem/interface/public/javascripts/stratagem.js +14 -12
- data/lib/stratagem/interface/views/index.haml +3 -3
- data/lib/stratagem/logger.rb +28 -2
- data/lib/stratagem/model.rb +6 -0
- data/lib/stratagem/model/application.rb +21 -134
- data/lib/stratagem/model/components/base.rb +1 -4
- data/lib/stratagem/model/components/controller.rb +1 -2
- data/lib/stratagem/model/components/model.rb +15 -15
- data/lib/stratagem/model/components/route.rb +3 -2
- data/lib/stratagem/model/components/view.rb +0 -1
- data/lib/stratagem/model/containers/base.rb +60 -0
- data/lib/stratagem/model/containers/gem.rb +25 -0
- data/lib/stratagem/model/containers/plugin.rb +11 -0
- data/lib/stratagem/model/containers/route.rb +19 -0
- data/lib/stratagem/model/parse_util.rb +3 -3
- data/lib/stratagem/model_builder.rb +1 -4
- data/lib/stratagem/rack_hack.rb +15 -0
- data/lib/stratagem/site_crawler.rb +5 -4
- data/lib/stratagem/snapshot.rb +5 -7
- data/spec/stratagem/configuration_spec.rb +32 -0
- data/stratagem.gemspec +5 -8
- data/templates/install/environments/stratagem.rb.erb +31 -2
- data/templates/install/script/stratagem +16 -0
- data/templates/install/tasks/stratagem.rake +2 -2
- metadata +36 -65
- data/bin/stratagem +0 -58
- data/lib/stratagem/scan.rb +0 -19
- data/lib/stratagem/scan/checks/email_address.rb +0 -15
- data/lib/stratagem/scan/checks/error_pages.rb +0 -25
- data/lib/stratagem/scan/result.rb +0 -45
- data/lib/stratagem/scanner.rb +0 -32
@@ -0,0 +1,38 @@
|
|
1
|
+
# Locates an instance of a user from configured credentials
|
2
|
+
|
3
|
+
module Stratagem::AutoMock
|
4
|
+
module UserLoader
|
5
|
+
def load_user_from_configuration(credentials)
|
6
|
+
possible_matches = []
|
7
|
+
auth_creds = credentials.authentication_parameters
|
8
|
+
model = credentials.model.constantize
|
9
|
+
@all_user_objects ||= model.all
|
10
|
+
log "\tloaded #{@all_user_objects.size} users from the database"
|
11
|
+
@all_user_objects.each do |user|
|
12
|
+
matching_attributes = matching_credentials(auth_creds, user)
|
13
|
+
possible_matches << [user, matching_attributes] if matching_attributes > 0
|
14
|
+
end
|
15
|
+
|
16
|
+
match = possible_matches.sort {|a,b| a[1] <=> b[1] }.last
|
17
|
+
if (match)
|
18
|
+
user = match.first
|
19
|
+
auth_creds.each {|k,v| user.stratagem.mock_attributes[k] = v }
|
20
|
+
user
|
21
|
+
else
|
22
|
+
nil
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def matching_credentials(authentication_parameters, user)
|
27
|
+
count = 0
|
28
|
+
authentication_parameters.each do |attribute, value|
|
29
|
+
begin
|
30
|
+
count += 1 if (value == user.send(attribute.to_sym))
|
31
|
+
rescue
|
32
|
+
end
|
33
|
+
end
|
34
|
+
count
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
data/lib/stratagem/client.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
require 'uri'
|
2
|
+
require 'zlib'
|
3
|
+
require 'base64'
|
2
4
|
|
3
5
|
module Stratagem
|
4
6
|
class Client
|
@@ -7,18 +9,29 @@ module Stratagem
|
|
7
9
|
end
|
8
10
|
|
9
11
|
def send(snapshot)
|
12
|
+
Stratagem.logger.phase('exporting')
|
10
13
|
Stratagem.logger.debug "Sending report to server"
|
14
|
+
|
11
15
|
url = URI.parse("#{@authentication.base_url}/snapshots")
|
12
16
|
req = Stratagem.ssl? ? Net::HTTPS::Post.new(url.path) : Net::HTTP::Post.new(url.path)
|
17
|
+
model = snapshot.model.export.to_json
|
18
|
+
puts "Size: #{model.size}"
|
19
|
+
compressed = Zlib::Deflate.deflate(model, Zlib::BEST_COMPRESSION)
|
20
|
+
base64 = Base64.encode64(compressed)
|
21
|
+
puts "Compressed size: #{compressed.size}"
|
22
|
+
puts "Compressed size base 64: #{base64.size}"
|
13
23
|
|
14
24
|
req.set_form_data({
|
15
25
|
'auth_token' => @authentication.credentials[:token],
|
16
26
|
'project_id' => @authentication.credentials[:project],
|
17
27
|
'timestamp' => snapshot.timestamp.to_i,
|
18
|
-
'model' =>
|
28
|
+
'model' => model
|
19
29
|
}, ';')
|
20
30
|
client = Stratagem.ssl? ? Net::HTTPS.new(url.host, url.port) : Net::HTTP.new(url.host, url.port)
|
21
|
-
res = client.start {|http|
|
31
|
+
res = client.start {|http|
|
32
|
+
http.read_timeout= 360
|
33
|
+
http.request(req)
|
34
|
+
}
|
22
35
|
puts "response:"
|
23
36
|
case res
|
24
37
|
when Net::HTTPSuccess, Net::HTTPRedirection
|
@@ -27,8 +40,6 @@ module Stratagem
|
|
27
40
|
else
|
28
41
|
res.error!
|
29
42
|
end
|
30
|
-
|
31
|
-
Stratagem.logger.phase('complete')
|
32
43
|
end
|
33
44
|
end
|
34
45
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Stratagem
|
2
|
+
module Configuration
|
3
|
+
class AuthAuth
|
4
|
+
attr_accessor :model, :authorized_to_view_others_data, :authorized_to_modify_others_data, :authorized_to_upload_files, :authentication_parameters
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
self.authorized_to_view_others_data = true
|
8
|
+
self.authorized_to_modify_others_data = false
|
9
|
+
self.authorized_to_upload_files = true
|
10
|
+
self.model = 'User'
|
11
|
+
end
|
12
|
+
|
13
|
+
def credentials(authentication_parameters)
|
14
|
+
self.authentication_parameters = authentication_parameters
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Stratagem
|
2
|
+
module Configuration
|
3
|
+
class Core
|
4
|
+
attr_accessor :use_transactional_crawling, :use_automatic_mocking
|
5
|
+
attr_reader :credentials
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@use_automatic_mocking = false
|
9
|
+
@use_transactional_crawling = true
|
10
|
+
@credentials = []
|
11
|
+
end
|
12
|
+
|
13
|
+
def authenticate_with(&block)
|
14
|
+
user = AuthAuth.new
|
15
|
+
block.call(user)
|
16
|
+
@credentials << user
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -7,20 +7,25 @@ module Stratagem::Crawler
|
|
7
7
|
module Authentication
|
8
8
|
include Stratagem::Crawler::TraceUtils
|
9
9
|
|
10
|
-
def
|
10
|
+
def user_model
|
11
|
+
model = nil
|
11
12
|
page = find_login_form
|
12
|
-
users = []
|
13
13
|
if (page)
|
14
14
|
form = page.login_form
|
15
15
|
attr_names = form.inputs.map {|input| input.guess_attribute.to_sym }
|
16
16
|
model = guess_login_model(attr_names)
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
17
|
+
end
|
18
|
+
log "Authenticating with model #{model.klass.name}"
|
19
|
+
model
|
20
|
+
end
|
21
|
+
|
22
|
+
def users
|
23
|
+
users = []
|
24
|
+
model = user_model()
|
25
|
+
if (model)
|
26
|
+
users = aquifer.instances_of(model.klass).select {|user| user.stratagem.mock_attributes.size > 0 }
|
22
27
|
else
|
23
|
-
log "ERROR:
|
28
|
+
log "ERROR: Unable to determine authentication model and / or form"
|
24
29
|
end
|
25
30
|
users
|
26
31
|
end
|
@@ -54,8 +59,7 @@ module Stratagem::Crawler
|
|
54
59
|
authentication.success = authentication.response_page.login_form.nil?
|
55
60
|
end
|
56
61
|
rescue
|
57
|
-
|
58
|
-
puts $!.backtrace
|
62
|
+
Stratagem.logger.error($!)
|
59
63
|
end
|
60
64
|
|
61
65
|
puts "authenticated? #{authentication.success}"
|
@@ -80,12 +84,13 @@ module Stratagem::Crawler
|
|
80
84
|
|
81
85
|
# if the first page has one or more redirects to it then use it; otherwise select with page with the fewest inputs
|
82
86
|
if (possibilities.first.inbound_edges(:redirect).size > 0)
|
83
|
-
|
87
|
+
authentication.login_page = possibilities.first
|
88
|
+
return authentication.login_page
|
84
89
|
else
|
85
90
|
page = possibilities.sort {|a,b| a.login_form.inputs.size <=> b.login_form.inputs.size }.first
|
86
91
|
if (page)
|
87
92
|
authentication.login_page = page
|
88
|
-
return
|
93
|
+
return authentication.login_page
|
89
94
|
end
|
90
95
|
end
|
91
96
|
else
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Stratagem::Crawler::Authentication
|
2
|
+
class AuthenticationData
|
3
|
+
attr_accessor :success, :login_page, :form, :response_page, :ssl, :authenticated_with
|
4
|
+
end
|
5
|
+
|
6
|
+
class Base
|
7
|
+
include Stratagem::Crawler::TraceUtils
|
8
|
+
|
9
|
+
def user_models
|
10
|
+
model = nil
|
11
|
+
page = find_login_form
|
12
|
+
if (page)
|
13
|
+
form = page.login_form
|
14
|
+
attr_names = form.inputs.map {|input| input.guess_attribute.to_sym }
|
15
|
+
model = guess_login_model(attr_names)
|
16
|
+
end
|
17
|
+
log "Authenticating with model #{model.klass.name}"
|
18
|
+
[model]
|
19
|
+
end
|
20
|
+
|
21
|
+
def guess_login_model(attr_names)
|
22
|
+
selections = application_model.models.select {|model|
|
23
|
+
puts "#{model.klass.name} - #{model.model_attributes.keys.inspect}"
|
24
|
+
intersect = (model.model_attributes.keys & attr_names)
|
25
|
+
intersect.size > 0
|
26
|
+
}.sort {|a,b|
|
27
|
+
a_intersect = (a.model_attributes.keys & attr_names)
|
28
|
+
b_intersect = (b.model_attributes.keys & attr_names)
|
29
|
+
b_intersect.size <=> a_intersect.size
|
30
|
+
}
|
31
|
+
|
32
|
+
explicit_model = application_model.models.find {|model| model.klass.name == 'User' }
|
33
|
+
selections.unshift explicit_model if explicit_model
|
34
|
+
|
35
|
+
puts "selecting model #{selections.first.klass.name} for authentication" if (selections.size > 0)
|
36
|
+
selections.first
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,140 @@
|
|
1
|
+
module Stratagem::Crawler::Authentication
|
2
|
+
class AuthenticationData
|
3
|
+
attr_accessor :success, :login_page, :form, :response_page, :ssl, :authenticated_with
|
4
|
+
end
|
5
|
+
|
6
|
+
class Base
|
7
|
+
include Stratagem::Crawler::TraceUtils
|
8
|
+
|
9
|
+
def users
|
10
|
+
users = []
|
11
|
+
user_models.each do |user_model|
|
12
|
+
users += aquifer.instances_of(user_model.klass).select {|user| user.stratagem.mock_attributes.size > 0 }
|
13
|
+
end
|
14
|
+
users
|
15
|
+
end
|
16
|
+
|
17
|
+
def reset_authentication
|
18
|
+
@authentication_data = nil
|
19
|
+
end
|
20
|
+
|
21
|
+
def authentication
|
22
|
+
unless @authentication_data
|
23
|
+
@authentication_data = AuthenticationData.new()
|
24
|
+
site_model.authentication = @authentication_data
|
25
|
+
end
|
26
|
+
@authentication_data
|
27
|
+
end
|
28
|
+
|
29
|
+
def authenticate(user, recursion_count=0)
|
30
|
+
reset_authentication
|
31
|
+
|
32
|
+
login(user)
|
33
|
+
route = application_model.routes.recognize(request.path, :post)
|
34
|
+
|
35
|
+
redirected_to = nil
|
36
|
+
page = site_model.add(route, controller, request, response) {|redirect_url| redirected_to = redirect_url }
|
37
|
+
authentication.response_page = page
|
38
|
+
|
39
|
+
begin
|
40
|
+
if (request.url == (redirected_to || '')) || (![200,302].include?(response.code.to_i))
|
41
|
+
authentication.success = false
|
42
|
+
else
|
43
|
+
authentication.success = authentication.response_page.login_form.nil?
|
44
|
+
end
|
45
|
+
rescue
|
46
|
+
Stratagem.logger.error($!)
|
47
|
+
end
|
48
|
+
|
49
|
+
puts "authenticated? #{authentication.success}"
|
50
|
+
if (response && authentication.success)
|
51
|
+
authentication.ssl = request.ssl?
|
52
|
+
authentication.authenticated_with = user
|
53
|
+
yield
|
54
|
+
logout
|
55
|
+
else
|
56
|
+
puts response.body
|
57
|
+
false
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def find_login_form
|
62
|
+
puts "finding login form"
|
63
|
+
if authentication.login_page.nil?
|
64
|
+
puts "locating login page"
|
65
|
+
puts "testing #{site_models.first.pages.size} pages"
|
66
|
+
possibilities = site_models.first.pages.select {|page| page.login_form != nil }
|
67
|
+
possibilities.sort! {|a,b| b.inbound_edges(:redirect).size <=> a.inbound_edges(:redirect).size }
|
68
|
+
|
69
|
+
# if the first page has one or more redirects to it then use it; otherwise select with page with the fewest inputs
|
70
|
+
if (possibilities.first.inbound_edges(:redirect).size > 0)
|
71
|
+
authentication.login_page = possibilities.first
|
72
|
+
return authentication.login_page
|
73
|
+
else
|
74
|
+
page = possibilities.sort {|a,b| a.login_form.inputs.size <=> b.login_form.inputs.size }.first
|
75
|
+
if (page)
|
76
|
+
authentication.login_page = page
|
77
|
+
return authentication.login_page
|
78
|
+
end
|
79
|
+
end
|
80
|
+
else
|
81
|
+
return authentication.login_page
|
82
|
+
end
|
83
|
+
nil
|
84
|
+
end
|
85
|
+
|
86
|
+
def logout
|
87
|
+
reset!
|
88
|
+
end
|
89
|
+
|
90
|
+
def login(user)
|
91
|
+
populate_login_form(user).submit {|action,params|
|
92
|
+
post(action, params)
|
93
|
+
}
|
94
|
+
end
|
95
|
+
|
96
|
+
def populate_login_form(user)
|
97
|
+
# set up the form
|
98
|
+
page = find_login_form
|
99
|
+
page.reload {|url| get url; [request,response] }
|
100
|
+
form = page.login_form
|
101
|
+
|
102
|
+
# map the input values
|
103
|
+
form.inputs.each do |input|
|
104
|
+
# try the expected
|
105
|
+
attribute_name = input.guess_attribute.to_sym
|
106
|
+
attribute_value = user.stratagem.read_mock_attribute(attribute_name) || input.value
|
107
|
+
|
108
|
+
# try again
|
109
|
+
if (attribute_value.nil? || attribute_value == '')
|
110
|
+
attribute_name = input.guess_alternate_attribute.to_sym
|
111
|
+
attribute_value = user.stratagem.read_mock_attribute(attribute_name) || input.value
|
112
|
+
end
|
113
|
+
|
114
|
+
# if it still failed is it a confirmation value? if so, try the original
|
115
|
+
if (attribute_value.nil? || attribute_value == '')
|
116
|
+
if (attribute_name.to_s =~ /confirm/)
|
117
|
+
possible_match = attribute_name.to_s.split('_').select {|a| a !~ /confirm/ }.join('_')
|
118
|
+
if user.stratagem.mock_attributes.keys.include?(possible_match)
|
119
|
+
attribute_value = user.stratagem.read_mock_attribute(possible_match) || input.value
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
|
125
|
+
if (input.kind_of? Stratagem::Crawler::Toggle)
|
126
|
+
input.check
|
127
|
+
elsif (user.stratagem.mock_attributes.keys.include?(attribute_name))
|
128
|
+
input.value = user.stratagem.read_mock_attribute(attribute_name) unless input.hidden?
|
129
|
+
elsif (attribute_name.to_s == 'authenticity_token')
|
130
|
+
puts input.value
|
131
|
+
else
|
132
|
+
puts user.stratagem.mock_attributes.inspect
|
133
|
+
puts "ERROR: Cannot find attribute #{attribute_name} in model #{user.class.name}"
|
134
|
+
end
|
135
|
+
end
|
136
|
+
form
|
137
|
+
end
|
138
|
+
|
139
|
+
end
|
140
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Stratagem::Crawler::Authentication
|
2
|
+
class Configured < Base
|
3
|
+
include Stratagem::AutoMock::UserLoader
|
4
|
+
|
5
|
+
def user_models
|
6
|
+
credentials.map {|user_credentials|
|
7
|
+
application_model.models.find {|model| model.klass.name == user_credentials.model }
|
8
|
+
}.compact
|
9
|
+
end
|
10
|
+
|
11
|
+
def users
|
12
|
+
log "Loading users for #{credentials.size} sets of credentials"
|
13
|
+
credentials.each do |user_credentials|
|
14
|
+
user = load_user_from_configuration(user_credentials)
|
15
|
+
if (user)
|
16
|
+
log "Loaded credentials for user #{user.id}: #{user.stratagem.mock_attributes.inspect}"
|
17
|
+
user.stratagem.related_objects.each do |object|
|
18
|
+
(objects_by_class[object.class] ||= []) << object
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
log "Loaded #{objects_by_class.keys.size} object types: #{objects_by_class.keys.inspect}"
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -6,12 +6,13 @@ module Stratagem::Crawler
|
|
6
6
|
route_infos, params = build_url(route_container, resolved_params)
|
7
7
|
route_info = route_infos.first
|
8
8
|
unknown_params = params.keys
|
9
|
+
puts "resolving parameter types - #{unknown_params.inspect}"
|
9
10
|
|
10
11
|
if (unknown_params.size > 0)
|
11
12
|
resolve_with_convention(unknown_params, resolved_params)
|
12
13
|
resolve_with_instrumentation(route_container, resolved_params)
|
13
14
|
resolve_id_with_convention(route_container, unknown_params, resolved_params)
|
14
|
-
log "\tresolved parameter types - #{resolved_params.inspect}"
|
15
|
+
log "\tresolved parameter types - #{resolved_params.keys.inspect}, unknown - #{unknown_params.inspect}"
|
15
16
|
end
|
16
17
|
|
17
18
|
if (resolved_params.size > 0)
|
@@ -43,7 +44,7 @@ module Stratagem::Crawler
|
|
43
44
|
# TODO inspect is a hack, refactor
|
44
45
|
if (invocation.args.include?(value.first)) || (invocation.args.inspect.include?('"'+value.first.to_s+'"'))
|
45
46
|
# found match
|
46
|
-
puts "\t\tresolved #{key} to #{invocation.model_class}"
|
47
|
+
puts "\t\tresolved #{key} to #{invocation.model_class} using instrumentation"
|
47
48
|
unknown_params.delete(key)
|
48
49
|
resolved_params[key] = invocation.model_class
|
49
50
|
progress += 1
|
@@ -58,15 +59,18 @@ module Stratagem::Crawler
|
|
58
59
|
end
|
59
60
|
|
60
61
|
def resolve_with_convention(unknown_params, resolved_params)
|
61
|
-
unknown_params.each do |param|
|
62
|
-
if (param =~ /_id$/)
|
62
|
+
unknown_params.clone.each do |param|
|
63
|
+
if (param.to_s =~ /_id$/)
|
63
64
|
begin
|
64
|
-
|
65
|
+
puts "\t\tattempting to resolve #{param.sub(/^:/,'').sub(/_id$/, '').camelize}"
|
66
|
+
model = param.sub(/^:/,'').sub(/_id$/, '').camelize.constantize
|
65
67
|
#success
|
66
68
|
resolved_params[param] = model
|
67
69
|
unknown_params.delete(param)
|
68
|
-
puts "\t\tresolved #{param} to #{model} using convention"
|
70
|
+
puts "\t\tresolved #{param} to #{model.name} using convention"
|
69
71
|
rescue NameError
|
72
|
+
puts "NAMEERROR: #{$!.message}"
|
73
|
+
rescue
|
70
74
|
puts "ERROR: #{$!.message}"
|
71
75
|
end
|
72
76
|
end
|
@@ -77,12 +81,12 @@ module Stratagem::Crawler
|
|
77
81
|
def resolve_id_with_convention(route_container, unknown_params, resolved_params)
|
78
82
|
if (unknown_params.include?('id'))
|
79
83
|
route_container.path.split('/').inject(nil) {|prev,part|
|
80
|
-
if (prev && part
|
84
|
+
if (prev && part =~ /^\:id/)
|
81
85
|
begin
|
82
86
|
resolved_params['id'] = prev.singularize.camelize.constantize
|
83
87
|
unknown_params.delete('id')
|
84
88
|
rescue
|
85
|
-
|
89
|
+
Stratagem.logger.error($!)
|
86
90
|
end
|
87
91
|
end
|
88
92
|
part
|