contrast-agent 4.9.1 → 4.10.0
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.
- checksums.yaml +4 -4
- data/.rspec +0 -1
- data/.rspec_parallel +6 -0
- data/ext/cs__contrast_patch/cs__contrast_patch.c +0 -1
- data/ext/cs__contrast_patch/cs__contrast_patch.h +0 -2
- data/lib/contrast/agent/assess/contrast_event.rb +0 -1
- data/lib/contrast/agent/assess/finalizers/hash.rb +0 -1
- data/lib/contrast/agent/assess/policy/patcher.rb +0 -1
- data/lib/contrast/agent/assess/policy/policy_scanner.rb +0 -2
- data/lib/contrast/agent/assess/policy/preshift.rb +8 -5
- data/lib/contrast/agent/assess/policy/propagation_method.rb +100 -57
- data/lib/contrast/agent/assess/policy/propagator/database_write.rb +0 -2
- data/lib/contrast/agent/assess/policy/propagator/match_data.rb +31 -11
- data/lib/contrast/agent/assess/policy/propagator/split.rb +3 -2
- data/lib/contrast/agent/assess/policy/propagator/substitution.rb +1 -0
- data/lib/contrast/agent/assess/policy/rewriter_patch.rb +0 -1
- data/lib/contrast/agent/assess/policy/source_method.rb +13 -17
- data/lib/contrast/agent/assess/policy/trigger/xpath.rb +0 -1
- data/lib/contrast/agent/assess/policy/trigger_method.rb +59 -83
- data/lib/contrast/agent/assess/property/evented.rb +2 -1
- data/lib/contrast/agent/assess/rule/provider/hardcoded_value_rule.rb +0 -1
- data/lib/contrast/agent/disable_reaction.rb +1 -1
- data/lib/contrast/agent/exclusion_matcher.rb +0 -4
- data/lib/contrast/agent/inventory/database_config.rb +117 -0
- data/lib/contrast/agent/inventory/dependency_usage_analysis.rb +5 -4
- data/lib/contrast/agent/inventory/policy/datastores.rb +2 -2
- data/lib/contrast/agent/middleware.rb +1 -0
- data/lib/contrast/agent/patching/policy/after_load_patch.rb +3 -0
- data/lib/contrast/agent/patching/policy/after_load_patcher.rb +18 -12
- data/lib/contrast/agent/patching/policy/module_policy.rb +2 -4
- data/lib/contrast/agent/patching/policy/patch.rb +5 -0
- data/lib/contrast/agent/patching/policy/patch_status.rb +3 -7
- data/lib/contrast/agent/patching/policy/patcher.rb +8 -8
- data/lib/contrast/agent/protect/policy/applies_no_sqli_rule.rb +1 -1
- data/lib/contrast/agent/protect/rule/no_sqli.rb +7 -53
- data/lib/contrast/agent/protect/rule/sql_sample_builder.rb +137 -0
- data/lib/contrast/agent/protect/rule/sqli.rb +7 -70
- data/lib/contrast/agent/reaction_processor.rb +1 -1
- data/lib/contrast/agent/request.rb +5 -2
- data/lib/contrast/agent/request_context.rb +19 -22
- data/lib/contrast/agent/static_analysis.rb +1 -1
- data/lib/contrast/agent/tracepoint_hook.rb +6 -1
- data/lib/contrast/agent/version.rb +1 -1
- data/lib/contrast/api/communication/messaging_queue.rb +12 -6
- data/lib/contrast/api/communication/service_lifecycle.rb +4 -1
- data/lib/contrast/api/communication/socket_client.rb +4 -4
- data/lib/contrast/api/decorators/agent_startup.rb +4 -4
- data/lib/contrast/api/decorators/application_startup.rb +6 -5
- data/lib/contrast/api/decorators/route_coverage.rb +24 -1
- data/lib/contrast/components/agent.rb +5 -2
- data/lib/contrast/components/assess.rb +6 -3
- data/lib/contrast/components/base.rb +2 -2
- data/lib/contrast/components/config.rb +1 -0
- data/lib/contrast/components/contrast_service.rb +4 -2
- data/lib/contrast/components/logger.rb +13 -8
- data/lib/contrast/components/scope.rb +9 -28
- data/lib/contrast/config/base_configuration.rb +14 -6
- data/lib/contrast/configuration.rb +19 -15
- data/lib/contrast/extension/assess/array.rb +1 -11
- data/lib/contrast/extension/assess/eval_trigger.rb +0 -20
- data/lib/contrast/extension/assess/fiber.rb +0 -11
- data/lib/contrast/extension/assess/hash.rb +0 -10
- data/lib/contrast/extension/assess/kernel.rb +1 -10
- data/lib/contrast/extension/assess/marshal.rb +3 -11
- data/lib/contrast/extension/assess/regexp.rb +0 -11
- data/lib/contrast/extension/assess/string.rb +1 -26
- data/lib/contrast/extension/extension.rb +61 -0
- data/lib/contrast/extension/protect/kernel.rb +0 -10
- data/lib/contrast/framework/grape/support.rb +174 -0
- data/lib/contrast/framework/manager.rb +42 -6
- data/lib/contrast/framework/rack/support.rb +1 -1
- data/lib/contrast/framework/rails/patch/assess_configuration.rb +0 -1
- data/lib/contrast/framework/rails/patch/support.rb +6 -3
- data/lib/contrast/framework/rails/railtie.rb +1 -1
- data/lib/contrast/framework/rails/rewrite/active_record_named.rb +1 -0
- data/lib/contrast/framework/rails/support.rb +60 -13
- data/lib/contrast/framework/sinatra/support.rb +1 -1
- data/lib/contrast/logger/log.rb +89 -15
- data/lib/contrast/utils/io_util.rb +1 -1
- data/lib/contrast/utils/ruby_ast_rewriter.rb +16 -13
- data/lib/contrast/utils/tag_util.rb +2 -1
- data/resources/assess/policy.json +197 -2
- data/resources/deadzone/policy.json +10 -0
- data/ruby-agent.gemspec +10 -1
- metadata +78 -12
- data/lib/contrast/utils/inventory_util.rb +0 -113
@@ -106,7 +106,7 @@ module Contrast
|
|
106
106
|
def _route_recurse controller, method, route
|
107
107
|
return if controller.nil? || controller.cs__class == NilClass
|
108
108
|
|
109
|
-
route_patterns = controller.routes.fetch(method
|
109
|
+
route_patterns = controller.routes.fetch(method) { [] }.map(&:first)
|
110
110
|
route_pattern = route_patterns&.find do |matcher|
|
111
111
|
matcher.params(route) # ::Mustermann::Sinatra match.
|
112
112
|
end
|
data/lib/contrast/logger/log.rb
CHANGED
@@ -13,6 +13,75 @@ require 'contrast/logger/time'
|
|
13
13
|
require 'contrast/components/config'
|
14
14
|
|
15
15
|
module Contrast
|
16
|
+
# This module allows us to dynamically weave timing into our code, so that only when the time is actually needed do
|
17
|
+
# we pay the penalty for that timing block
|
18
|
+
module TraceTiming
|
19
|
+
def methods_to_time
|
20
|
+
@_methods_to_time ||= []
|
21
|
+
end
|
22
|
+
|
23
|
+
# Store info about methods for later patching.
|
24
|
+
METHOD_INFO = Struct.new(:clazz, :method_name, :custom_msg, :aliased)
|
25
|
+
|
26
|
+
# Add a method to the list of methods to be trace timed if logger set to TRACE. Enables trace timing after if
|
27
|
+
# logger set to TRACE.
|
28
|
+
#
|
29
|
+
# @params: clazz [Class] the class of the method to time.
|
30
|
+
# @params: method [Symbol] the method to time.
|
31
|
+
# @params: method [String] optional custom logging message.
|
32
|
+
def add_method_to_trace_timing clazz, method, msg = nil
|
33
|
+
methods_to_time.append(METHOD_INFO.new(clazz, method, msg, false))
|
34
|
+
enable_trace_timing if logger.level == ::Ougai::Logging::TRACE
|
35
|
+
end
|
36
|
+
|
37
|
+
# Add a method to the list of methods to be trace timed if logger set to TRACE. Enables trace timing after if
|
38
|
+
# logger set to TRACE.
|
39
|
+
#
|
40
|
+
# @params: method_spec [METHOD_INFO] specs about the method to be timed.
|
41
|
+
# @params: class_method [Boolean] whether this is or isn't a class/module method.
|
42
|
+
def trace_time_class_method meth_spec, class_method
|
43
|
+
untimed_func_symbol = "untimed_#{ meth_spec.method_name }".to_sym
|
44
|
+
send_to = class_method ? meth_spec.clazz.cs__singleton_class : meth_spec.clazz
|
45
|
+
meth_spec.clazz.class_eval do
|
46
|
+
include Contrast::Components::Logger::InstanceMethods
|
47
|
+
extend Contrast::Components::Logger::InstanceMethods
|
48
|
+
|
49
|
+
send_to.send(:alias_method, untimed_func_symbol, meth_spec.method_name)
|
50
|
+
meth_spec.aliased = true
|
51
|
+
|
52
|
+
log_message = "Elapsed time for #{ meth_spec.method_name }."
|
53
|
+
log_message = meth_spec.custom_message if meth_spec.custom_msg
|
54
|
+
|
55
|
+
send_to.send(:define_method, meth_spec.method_name) do |*args, **kwargs, &block| # rubocop:disable Performance/Kernel/DefineMethod
|
56
|
+
start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
57
|
+
rv = if kwargs.empty?
|
58
|
+
send(untimed_func_symbol, *args, &block)
|
59
|
+
else
|
60
|
+
send(untimed_func_symbol, *args, **kwargs, &block)
|
61
|
+
end
|
62
|
+
delta = Process.clock_gettime(Process::CLOCK_MONOTONIC) - start
|
63
|
+
logger.trace(log_message, elapsed: delta * 1000)
|
64
|
+
rv
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
# Enable trace timing of methods specified in @_methods_to_time via aliasing.
|
70
|
+
def enable_trace_timing
|
71
|
+
methods_to_time.each do |meth_spec|
|
72
|
+
next if meth_spec.aliased
|
73
|
+
|
74
|
+
is_class_method = meth_spec.clazz.singleton_methods(false).include?(meth_spec.method_name)
|
75
|
+
trace_time_class_method meth_spec, is_class_method
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
module Contrast
|
82
|
+
# Used as a wrapper around our logging. The module option specifically adds in a new method for error that raises the
|
83
|
+
# logged exception, used in testing so that we can see if anything unexpected happens without it being swallowed
|
84
|
+
# while still providing safe options for customers.
|
16
85
|
module Logger
|
17
86
|
# For development set following env var to raise logged exceptions instead of just logging.
|
18
87
|
if ENV['CONTRAST__AGENT__RUBY_MORE_COWBELL']
|
@@ -20,22 +89,22 @@ module Contrast
|
|
20
89
|
alias_method :cs__error, :error
|
21
90
|
alias_method :cs__warn, :warn
|
22
91
|
|
23
|
-
def error
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
raise exc if exc && exc.cs__class < Exception
|
92
|
+
def error *args, **kwargs
|
93
|
+
if kwargs.empty?
|
94
|
+
cs__error(*args)
|
95
|
+
else
|
96
|
+
cs__error(*args, **kwargs)
|
97
|
+
end
|
98
|
+
args.each { |arg| raise arg if arg && arg.cs__class < Exception }
|
31
99
|
end
|
32
100
|
end
|
33
101
|
end
|
34
102
|
|
35
|
-
# This class functions to serve as a wrapper around our logging, as we need
|
36
|
-
#
|
103
|
+
# This class functions to serve as a wrapper around our logging, as we need to be able to dynamically update
|
104
|
+
# level based on updates to TeamServer.
|
37
105
|
class Log
|
38
106
|
include Singleton
|
107
|
+
include ::Contrast::TraceTiming
|
39
108
|
|
40
109
|
DEFAULT_NAME = 'contrast.log'
|
41
110
|
DEFAULT_LEVEL = ::Ougai::Logging::Severity::INFO
|
@@ -49,8 +118,8 @@ module Contrast
|
|
49
118
|
update
|
50
119
|
end
|
51
120
|
|
52
|
-
# Given new settings from TeamServer, update our logging to use the new
|
53
|
-
#
|
121
|
+
# Given new settings from TeamServer, update our logging to use the new file and level, assuming they weren't
|
122
|
+
# set by local configuration.
|
54
123
|
#
|
55
124
|
# @param log_file [String] the file to which to log, as provided by TeamServer settings
|
56
125
|
# @param log_level [String] the level at which to log, as provided by TeamServer settings
|
@@ -67,6 +136,8 @@ module Contrast
|
|
67
136
|
@previous_path = current_path
|
68
137
|
@previous_level = current_level_const
|
69
138
|
|
139
|
+
enable_trace_timing if current_level_const == ::Ougai::Logging::TRACE
|
140
|
+
|
70
141
|
@_logger = build(path: current_path, level_const: current_level_const)
|
71
142
|
# If we're logging to a new path, then let's start it w/ our helpful
|
72
143
|
# data gathering messages
|
@@ -76,6 +147,9 @@ module Contrast
|
|
76
147
|
logger.error('Unable to process update to LoggerManager.', e)
|
77
148
|
else
|
78
149
|
puts 'Unable to process update to LoggerManager.'
|
150
|
+
raise e if ENV['CONTRAST__AGENT__RUBY_MORE_COWBELL']
|
151
|
+
|
152
|
+
puts e.message
|
79
153
|
puts e.backtrace.join("\n")
|
80
154
|
end
|
81
155
|
end
|
@@ -158,7 +232,8 @@ module Contrast
|
|
158
232
|
# @return [::Ougai::Logging::Severity] the level at which to log
|
159
233
|
def find_valid_level log_level
|
160
234
|
config = ::Contrast::CONFIG.root.agent.logger
|
161
|
-
config_level = config
|
235
|
+
config_level = config&.level&.length&.positive? ? config.level : nil
|
236
|
+
|
162
237
|
valid_level(config_level || log_level)
|
163
238
|
end
|
164
239
|
|
@@ -174,8 +249,7 @@ module Contrast
|
|
174
249
|
DEFAULT_LEVEL
|
175
250
|
end
|
176
251
|
|
177
|
-
# Log that the Agent log has changed and include some default information
|
178
|
-
# at the start of the log.
|
252
|
+
# Log that the Agent log has changed and include some default information at the start of the log.
|
179
253
|
def log_update
|
180
254
|
logger.debug('Initialized new contrast agent logger')
|
181
255
|
logger.debug_with_time('middleware: log environment') do
|
@@ -6,7 +6,7 @@ require 'contrast/components/logger'
|
|
6
6
|
module Contrast
|
7
7
|
module Utils
|
8
8
|
# Util for information about an IO
|
9
|
-
|
9
|
+
module IOUtil
|
10
10
|
extend Contrast::Components::Logger::InstanceMethods
|
11
11
|
|
12
12
|
# We're only going to call rewind on things that we believe are safe to
|
@@ -36,36 +36,39 @@ module Contrast
|
|
36
36
|
# the replace within the given node.
|
37
37
|
def on_dstr node
|
38
38
|
return if node.children.all? { |child_node| child_node.type == :str }
|
39
|
-
|
40
39
|
new_content = +'('
|
41
|
-
|
40
|
+
idx = 0
|
41
|
+
while idx < node.children.size
|
42
|
+
#node.children.each_with_index do |child_node, index|
|
43
|
+
child_node = node.children[idx]
|
42
44
|
# A begin node looks like #{some_code} in ruby, we do a substring
|
43
45
|
# from [2...-1] to get rid of the #{ & trailing }.
|
44
46
|
if child_node.type == :begin
|
45
47
|
code = child_node.
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
48
|
+
location.
|
49
|
+
expression.
|
50
|
+
source_buffer.
|
51
|
+
source[child_node.location.begin.begin_pos...child_node.location.end.end_pos]
|
50
52
|
code = code[2...-1]
|
51
53
|
new_content += "((#{ code }).to_s)"
|
52
54
|
|
53
|
-
|
54
|
-
|
55
|
-
|
55
|
+
# For interpolations that use class, instance, or global variables,
|
56
|
+
# those are NOT within a begin block, but instead are a ivar, cvar,
|
57
|
+
# or gvar node, not stripping of interpolation markers required.
|
56
58
|
elsif VARIABLES.include?(child_node.type)
|
57
59
|
variable = child_node.children.first
|
58
60
|
new_content << "((#{ variable }).to_s)"
|
59
61
|
|
60
|
-
|
61
|
-
|
62
|
-
|
62
|
+
# When interpolation includes strings before or after an
|
63
|
+
# interpolation they are simple :str nodes, in order to preserve
|
64
|
+
# escaping we need to do a dump of the string value.
|
63
65
|
elsif child_node.type == :str
|
64
66
|
literal_value = child_node.children.first
|
65
67
|
literal_value = literal_value.dump[1...-1]
|
66
68
|
new_content << "\"#{ literal_value }\""
|
67
69
|
end
|
68
|
-
new_content << ' + ' unless
|
70
|
+
new_content << ' + ' unless idx == node.children.length - 1
|
71
|
+
idx += 1
|
69
72
|
end
|
70
73
|
new_content << ')'
|
71
74
|
if node.location.cs__respond_to?(:heredoc_body)
|
@@ -8,7 +8,8 @@ module Contrast
|
|
8
8
|
class << self
|
9
9
|
# Determine if the given array of tags is covered by the other
|
10
10
|
#
|
11
|
-
# @param remaining_ranges [Array<Contrast::Agent::Assess::Tag>] the tags left that haven't been covered by
|
11
|
+
# @param remaining_ranges [Array<Contrast::Agent::Assess::Tag>] the tags left that haven't been covered by
|
12
|
+
# those given
|
12
13
|
# @param ranges Array<Contrast::Agent::Assess::Tag> the tags that are covering the first
|
13
14
|
def covered? remaining_ranges, ranges
|
14
15
|
return true unless remaining_ranges&.any?
|
@@ -34,6 +34,23 @@
|
|
34
34
|
"type": "BODY",
|
35
35
|
"tags":["NO_NEWLINES", "CROSS_SITE"]
|
36
36
|
}, {
|
37
|
+
"class_name":"ActionDispatch::Request",
|
38
|
+
"instance_method": true,
|
39
|
+
"method_visibility": "public",
|
40
|
+
"method_name": "body",
|
41
|
+
"source": "P0",
|
42
|
+
"target": "R",
|
43
|
+
"type": "BODY",
|
44
|
+
"tags":["NO_NEWLINES", "CROSS_SITE"]
|
45
|
+
}, {
|
46
|
+
"class_name":"ActionDispatch::Cookies::CookieJar",
|
47
|
+
"instance_method": true,
|
48
|
+
"method_visibility": "public",
|
49
|
+
"method_name": "[]",
|
50
|
+
"target": "R",
|
51
|
+
"type": "COOKIE",
|
52
|
+
"tags":["NO_NEWLINES", "CROSS_SITE"]
|
53
|
+
}, {
|
37
54
|
"class_name":"Rack::Request::Helpers",
|
38
55
|
"instance_method": true,
|
39
56
|
"method_visibility": "public",
|
@@ -129,10 +146,45 @@
|
|
129
146
|
"target":"R",
|
130
147
|
"type":"PARAMETER",
|
131
148
|
"tags":["CROSS_SITE"]
|
149
|
+
}, {
|
150
|
+
"class_name":"Grape::Env",
|
151
|
+
"instance_method": true,
|
152
|
+
"method_visibility": "public",
|
153
|
+
"method_name":"[]",
|
154
|
+
"source": "P0",
|
155
|
+
"target":"R",
|
156
|
+
"type":"HEADER",
|
157
|
+
"tags":["CROSS_SITE"]
|
158
|
+
}, {
|
159
|
+
"class_name":"Grape::Request",
|
160
|
+
"instance_method": true,
|
161
|
+
"method_visibility": "public",
|
162
|
+
"method_name":"headers",
|
163
|
+
"source": "P0",
|
164
|
+
"target":"R",
|
165
|
+
"type":"HEADER",
|
166
|
+
"tags":["NO_NEWLINES", "CROSS_SITE"]
|
167
|
+
}, {
|
168
|
+
"class_name":"Grape::Request",
|
169
|
+
"instance_method": true,
|
170
|
+
"method_visibility": "public",
|
171
|
+
"method_name":"body",
|
172
|
+
"target":"R",
|
173
|
+
"type":"BODY",
|
174
|
+
"tags":["CROSS_SITE"]
|
175
|
+
}, {
|
176
|
+
"class_name":"Grape::Validations::Base",
|
177
|
+
"instance_method": true,
|
178
|
+
"method_visibility": "public",
|
179
|
+
"method_name":"validate!",
|
180
|
+
"source": "P0",
|
181
|
+
"target":"R",
|
182
|
+
"type":"PARAMETER",
|
183
|
+
"tags":["CROSS_SITE"]
|
132
184
|
}
|
133
185
|
],
|
134
186
|
"propagators":[
|
135
|
-
|
187
|
+
{
|
136
188
|
"class_name":"String",
|
137
189
|
"instance_method": true,
|
138
190
|
"method_visibility": "public",
|
@@ -140,7 +192,7 @@
|
|
140
192
|
"source":"O",
|
141
193
|
"target":"R",
|
142
194
|
"action":"KEEP"
|
143
|
-
},
|
195
|
+
}, {
|
144
196
|
"class_name": "String",
|
145
197
|
"instance_method": true,
|
146
198
|
"method_visibility": "public",
|
@@ -722,6 +774,24 @@
|
|
722
774
|
"patch_method": "select_tagger",
|
723
775
|
"source": "O",
|
724
776
|
"target": "R"
|
777
|
+
},{
|
778
|
+
"class_name":"CGI::Util",
|
779
|
+
"method_name":"unescape",
|
780
|
+
"instance_method": true,
|
781
|
+
"method_visibility": "public",
|
782
|
+
"source":"P0",
|
783
|
+
"target":"R",
|
784
|
+
"action":"SPLAT",
|
785
|
+
"tags":[],
|
786
|
+
"untags":[]
|
787
|
+
}, {
|
788
|
+
"class_name":"StringIO",
|
789
|
+
"instance_method": true,
|
790
|
+
"method_visibility": "public",
|
791
|
+
"method_name": "read",
|
792
|
+
"source": "O",
|
793
|
+
"target": "R",
|
794
|
+
"action": "SPLAT"
|
725
795
|
}, {
|
726
796
|
"class_name":"CGI::Util",
|
727
797
|
"method_name":"escapeHTML",
|
@@ -742,6 +812,16 @@
|
|
742
812
|
"action":"SPLAT",
|
743
813
|
"tags":["HTML_ENCODED"],
|
744
814
|
"untags":["HTML_DECODED"]
|
815
|
+
}, {
|
816
|
+
"class_name":"Rack::Utils",
|
817
|
+
"method_name":"escape_html",
|
818
|
+
"instance_method": false,
|
819
|
+
"method_visibility": "public",
|
820
|
+
"source":"P0",
|
821
|
+
"target":"R",
|
822
|
+
"action":"SPLAT",
|
823
|
+
"tags":["HTML_ENCODED"],
|
824
|
+
"untags":["HTML_DECODED"]
|
745
825
|
}, {
|
746
826
|
"class_name":"CGI::Util",
|
747
827
|
"method_name":"h",
|
@@ -1287,6 +1367,18 @@
|
|
1287
1367
|
"instance_method": true,
|
1288
1368
|
"method_visibility": "public",
|
1289
1369
|
"source":"P0"
|
1370
|
+
}, {
|
1371
|
+
"class_name":"Rack::Response",
|
1372
|
+
"method_name":"body=",
|
1373
|
+
"instance_method": true,
|
1374
|
+
"method_visibility": "public",
|
1375
|
+
"source":"P0"
|
1376
|
+
}, {
|
1377
|
+
"class_name":"Rack::Response",
|
1378
|
+
"method_name":"write",
|
1379
|
+
"instance_method": true,
|
1380
|
+
"method_visibility": "public",
|
1381
|
+
"source":"P0"
|
1290
1382
|
}, {
|
1291
1383
|
"class_name":"Sinatra::Helpers",
|
1292
1384
|
"method_name":"body",
|
@@ -1347,12 +1439,108 @@
|
|
1347
1439
|
"method_visibility": "public",
|
1348
1440
|
"method_name":"async_exec",
|
1349
1441
|
"source":"P0"
|
1442
|
+
}, {
|
1443
|
+
"class_name":"ActiveRecord::Relation::Calculations",
|
1444
|
+
"instance_method": true,
|
1445
|
+
"method_visibility": "public",
|
1446
|
+
"method_name":"calculate",
|
1447
|
+
"source":"P0"
|
1448
|
+
}, {
|
1449
|
+
"class_name":"ActiveRecord::FinderMethods",
|
1450
|
+
"instance_method": true,
|
1451
|
+
"method_visibility": "public",
|
1452
|
+
"method_name":"exists?",
|
1453
|
+
"source":"P0"
|
1454
|
+
}, {
|
1455
|
+
"class_name":"ActiveRecord::FinderMethods",
|
1456
|
+
"instance_method": true,
|
1457
|
+
"method_visibility": "public",
|
1458
|
+
"method_name":"find_by",
|
1459
|
+
"source":"P0"
|
1350
1460
|
}, {
|
1351
1461
|
"class_name":"ActiveRecord::Querying",
|
1352
1462
|
"instance_method": false,
|
1353
1463
|
"method_visibility": "public",
|
1354
1464
|
"method_name":"select",
|
1355
1465
|
"source":"P0"
|
1466
|
+
}, {
|
1467
|
+
"class_name":"ActiveRecord::QueryMethods",
|
1468
|
+
"instance_method": true,
|
1469
|
+
"method_visibility": "public",
|
1470
|
+
"method_name":"from",
|
1471
|
+
"source":"P0"
|
1472
|
+
}, {
|
1473
|
+
"class_name":"ActiveRecord::QueryMethods",
|
1474
|
+
"instance_method": true,
|
1475
|
+
"method_visibility": "public",
|
1476
|
+
"method_name":"group",
|
1477
|
+
"source":"P0"
|
1478
|
+
}, {
|
1479
|
+
"class_name":"ActiveRecord::QueryMethods",
|
1480
|
+
"instance_method": true,
|
1481
|
+
"method_visibility": "public",
|
1482
|
+
"method_name":"having",
|
1483
|
+
"source":"P0"
|
1484
|
+
}, {
|
1485
|
+
"class_name":"ActiveRecord::QueryMethods",
|
1486
|
+
"instance_method": true,
|
1487
|
+
"method_visibility": "public",
|
1488
|
+
"method_name":"joins",
|
1489
|
+
"source":"P0"
|
1490
|
+
}, {
|
1491
|
+
"class_name":"ActiveRecord::QueryMethods",
|
1492
|
+
"instance_method": true,
|
1493
|
+
"method_visibility": "public",
|
1494
|
+
"method_name":"lock",
|
1495
|
+
"source":"P0"
|
1496
|
+
}, {
|
1497
|
+
"class_name":"ActiveRecord::QueryMethods",
|
1498
|
+
"instance_method": true,
|
1499
|
+
"method_visibility": "public",
|
1500
|
+
"method_name":"select",
|
1501
|
+
"source":"P0"
|
1502
|
+
}, {
|
1503
|
+
"class_name":"ActiveRecord::QueryMethods",
|
1504
|
+
"instance_method": true,
|
1505
|
+
"method_visibility": "public",
|
1506
|
+
"method_name":"reselect",
|
1507
|
+
"source":"P0"
|
1508
|
+
}, {
|
1509
|
+
"class_name":"ActiveRecord::QueryMethods",
|
1510
|
+
"instance_method": true,
|
1511
|
+
"method_visibility": "public",
|
1512
|
+
"method_name":"where",
|
1513
|
+
"source":"P0"
|
1514
|
+
}, {
|
1515
|
+
"class_name":"ActiveRecord::QueryMethods",
|
1516
|
+
"instance_method": true,
|
1517
|
+
"method_visibility": "public",
|
1518
|
+
"method_name":"rewhere",
|
1519
|
+
"source":"P0"
|
1520
|
+
}, {
|
1521
|
+
"class_name":"ActiveRecord::QueryMethods::WhereChain",
|
1522
|
+
"instance_method": true,
|
1523
|
+
"method_visibility": "public",
|
1524
|
+
"method_name":"not",
|
1525
|
+
"source":"P0"
|
1526
|
+
}, {
|
1527
|
+
"class_name":"ActiveRecord::Relation",
|
1528
|
+
"instance_method": true,
|
1529
|
+
"method_visibility": "public",
|
1530
|
+
"method_name":"delete_by",
|
1531
|
+
"source":"P0"
|
1532
|
+
}, {
|
1533
|
+
"class_name":"ActiveRecord::Relation",
|
1534
|
+
"instance_method": true,
|
1535
|
+
"method_visibility": "public",
|
1536
|
+
"method_name":"destroy_by",
|
1537
|
+
"source":"P0"
|
1538
|
+
}, {
|
1539
|
+
"class_name":"ActiveRecord::Relation",
|
1540
|
+
"instance_method": true,
|
1541
|
+
"method_visibility": "public",
|
1542
|
+
"method_name":"update_all",
|
1543
|
+
"source":"P0"
|
1356
1544
|
}
|
1357
1545
|
]
|
1358
1546
|
}, {
|
@@ -1685,6 +1873,13 @@
|
|
1685
1873
|
"method_visibility": "public",
|
1686
1874
|
"method_name": "redirect_to",
|
1687
1875
|
"source": "P0"
|
1876
|
+
},
|
1877
|
+
{
|
1878
|
+
"class_name": "Grape::DSL::InsideRoute",
|
1879
|
+
"instance_method": true,
|
1880
|
+
"method_visibility": "public",
|
1881
|
+
"method_name": "redirect",
|
1882
|
+
"source": "P0"
|
1688
1883
|
}
|
1689
1884
|
]
|
1690
1885
|
}, {
|