asana_exception_notifier 0.0.4 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/lib/asana_exception_notifier.rb +1 -0
- data/lib/asana_exception_notifier/classes/asana.rb +4 -6
- data/lib/asana_exception_notifier/classes/error_page.rb +33 -14
- data/lib/asana_exception_notifier/classes/unsafe_filter.rb +53 -0
- data/lib/asana_exception_notifier/helpers/application_helper.rb +29 -9
- data/lib/asana_exception_notifier/helpers/heredoc_helper.rb +3 -8
- data/lib/asana_exception_notifier/version.rb +1 -1
- metadata +2 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 520178c0df0b87ab02ee7a9e05b3c37f11570796
|
4
|
+
data.tar.gz: cf6746459b95fd0db6f7e7ba5ad184790c0cebfe
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8323b25c7d23852e0be40cd00ce98c421544b66f28b5190a44fbafce960cbbbc850e147b28f4f272539361070cd6a410ac6faab265035acace0214a149854506
|
7
|
+
data.tar.gz: 2c94dfe47678d0942c5a3035babcfbb87d46d20084d6ee6e5e99c023ac87a7c2fa994a1991136e2e4a9394703d7947aec77dbdbb6d28023c14155c978b7b9cef
|
data/Gemfile.lock
CHANGED
@@ -13,11 +13,9 @@ module ExceptionNotifier
|
|
13
13
|
attr_reader :initial_options, :default_options
|
14
14
|
|
15
15
|
def initialize(options)
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
parse_options(@initial_options)
|
20
|
-
end
|
16
|
+
super
|
17
|
+
@initial_options = options.symbolize_keys.reject { |_key, value| value.blank? }
|
18
|
+
parse_options(@initial_options)
|
21
19
|
end
|
22
20
|
|
23
21
|
def call(exception, options = {})
|
@@ -98,7 +96,7 @@ module ExceptionNotifier
|
|
98
96
|
end
|
99
97
|
|
100
98
|
def upload_log_file_to_task(error_page, task_data)
|
101
|
-
archives = error_page.
|
99
|
+
archives = error_page.fetch_all_archives
|
102
100
|
archives.each do |zip|
|
103
101
|
upload_archive(zip, task_data)
|
104
102
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require_relative '../helpers/application_helper'
|
2
|
+
require_relative './unsafe_filter'
|
2
3
|
module AsanaExceptionNotifier
|
3
4
|
# class used for rendering the template for exception
|
4
5
|
class ErrorPage
|
@@ -41,11 +42,12 @@ module AsanaExceptionNotifier
|
|
41
42
|
server: Socket.gethostname,
|
42
43
|
exception: @exception,
|
43
44
|
request: @request,
|
44
|
-
environment:
|
45
|
+
environment: @request.respond_to?(:filtered_env) ? @request.filtered_env : @env,
|
45
46
|
rails_root: defined?(Rails) ? Rails.root : nil,
|
46
47
|
process: $PROCESS_ID,
|
47
48
|
data: (@env.blank? ? {} : @env.fetch(:'exception_notifier.exception_data', {})).merge(@options[:data] || {}),
|
48
49
|
exception_data: exception_data,
|
50
|
+
exception_service_data: exception_service,
|
49
51
|
request_data: setup_env_params,
|
50
52
|
uname: Sys::Uname.uname,
|
51
53
|
timestamp: @timestamp,
|
@@ -57,24 +59,37 @@ module AsanaExceptionNotifier
|
|
57
59
|
{
|
58
60
|
error_class: @exception.class.to_s,
|
59
61
|
message: @exception.respond_to?(:message) ? @exception.message : exception.inspect,
|
60
|
-
backtrace: @exception.respond_to?(:backtrace) ? @exception.backtrace :
|
61
|
-
cause: @exception.respond_to?(:cause) ? @exception.cause :
|
62
|
+
backtrace: @exception.respond_to?(:backtrace) ? (@exception.backtrace || []).join("\n") : nil,
|
63
|
+
cause: @exception.respond_to?(:cause) ? @exception.cause : nil
|
64
|
+
}
|
65
|
+
end
|
66
|
+
|
67
|
+
def exception_service
|
68
|
+
{
|
69
|
+
service_class: @exception.respond_to?(:service_class) ? @exception.service_class : nil,
|
70
|
+
arguments: @exception.respond_to?(:service_arguments) ? filter_params(@exception.service_arguments).inspect.gsub(',', ",\n") : nil,
|
71
|
+
service_method: @exception.respond_to?(:service_method) ? @exception.service_method : nil,
|
72
|
+
trace: @exception.respond_to?(:service_backtrace) ? @exception.service_backtrace : nil
|
62
73
|
}
|
63
74
|
end
|
64
75
|
|
65
76
|
def setup_env_params
|
66
77
|
{
|
67
|
-
url:
|
78
|
+
url: @request.respond_to?(:original_url) ? @request.original_url : @request.path_info,
|
68
79
|
referrer: @request.referer,
|
69
80
|
http_method: action_dispatch? ? @request.method : @request.request_method,
|
70
|
-
ip_address:
|
71
|
-
parameters:
|
81
|
+
ip_address: @request.respond_to?(:remote_ip) ? @request.remote_ip : @request.ip,
|
82
|
+
parameters: @request.respond_to?(:filtered_parameters) ? filter_params(@request.filtered_parameters) : filter_params(request_params),
|
72
83
|
session: @request.session,
|
73
84
|
cookies: @request.cookies,
|
74
85
|
user_agent: @request.user_agent
|
75
86
|
}
|
76
87
|
end
|
77
88
|
|
89
|
+
def filter_params(params)
|
90
|
+
AsanaExceptionNotifier::UnsafeFilter.new(params, @options.fetch(:unsafe_options, []))
|
91
|
+
end
|
92
|
+
|
78
93
|
def request_params
|
79
94
|
@request.params
|
80
95
|
rescue
|
@@ -100,7 +115,7 @@ module AsanaExceptionNotifier
|
|
100
115
|
def add_to_links(links, prefix, options = {})
|
101
116
|
expected_value = parse_fieldset_value(options)
|
102
117
|
return unless expected_value.present?
|
103
|
-
prefix_name = set_fieldset_key(links, prefix
|
118
|
+
prefix_name = set_fieldset_key(links, prefix, 'basic_info')
|
104
119
|
links[prefix_name][options[:key]] = expected_value
|
105
120
|
end
|
106
121
|
|
@@ -123,14 +138,18 @@ module AsanaExceptionNotifier
|
|
123
138
|
tempfile_details(tempfile).slice(:filename, :path).values
|
124
139
|
end
|
125
140
|
|
141
|
+
def fetch_all_archives
|
142
|
+
fetch_archives
|
143
|
+
rescue
|
144
|
+
[]
|
145
|
+
end
|
146
|
+
|
126
147
|
def fetch_archives(output = render_template)
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
split_archive(archive, "part_#{filename}", 1024 * 1024 * 100)
|
133
|
-
end
|
148
|
+
return [] if output.blank?
|
149
|
+
filename, path = create_tempfile(output)
|
150
|
+
archive = compress_files(File.dirname(path), filename, [expanded_path(path)])
|
151
|
+
remove_tempfile(path)
|
152
|
+
split_archive(archive, "part_#{filename}", 1024 * 1024 * 100)
|
134
153
|
end
|
135
154
|
|
136
155
|
def remove_tempfile(path)
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require_relative '../helpers/application_helper'
|
2
|
+
module AsanaExceptionNotifier
|
3
|
+
# class used to filter unsafe params
|
4
|
+
class UnsafeFilter
|
5
|
+
include AsanaExceptionNotifier::ApplicationHelper
|
6
|
+
|
7
|
+
UNSAFE_OPTIONS = %w(
|
8
|
+
password password_confirmation new_password new_password_confirmation
|
9
|
+
old_password email_address email authenticity_token utf8
|
10
|
+
).freeze
|
11
|
+
|
12
|
+
attr_reader :arguments, :unsafe_options
|
13
|
+
|
14
|
+
def initialize(arguments, unsafe_options = [])
|
15
|
+
@unsafe_options = unsafe_options.present? && unsafe_options.is_a?(Array) ? unsafe_options.map(&:to_s) : []
|
16
|
+
@arguments = arguments.present? ? arguments : {}
|
17
|
+
remove_unsafe(@arguments)
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def remove_unsafe(args)
|
23
|
+
return args if args.blank?
|
24
|
+
args.delete(:attributes!)
|
25
|
+
remove_blank(args)
|
26
|
+
remove_unsafe_from_object(args)
|
27
|
+
args
|
28
|
+
end
|
29
|
+
|
30
|
+
def remove_unsafe_from_object(args)
|
31
|
+
if args.is_a?(Hash)
|
32
|
+
args.each_pair do |key, value|
|
33
|
+
verify_unsafe_pair(key, value)
|
34
|
+
end
|
35
|
+
else
|
36
|
+
remove_unsafe(value: args)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def unsafe?(key)
|
41
|
+
@unsafe_options.include?(key) || AsanaExceptionNotifier::UnsafeFilter::UNSAFE_OPTIONS.include?(key)
|
42
|
+
end
|
43
|
+
|
44
|
+
def verify_unsafe_pair(key, value)
|
45
|
+
case value
|
46
|
+
when Hash
|
47
|
+
remove_unsafe(value)
|
48
|
+
else
|
49
|
+
args.delete(key) if unsafe?(key.to_s)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -23,7 +23,8 @@ module AsanaExceptionNotifier
|
|
23
23
|
tags: [],
|
24
24
|
notes: '',
|
25
25
|
name: '',
|
26
|
-
template_path: nil
|
26
|
+
template_path: nil,
|
27
|
+
unsafe_options: []
|
27
28
|
}
|
28
29
|
end
|
29
30
|
|
@@ -43,8 +44,6 @@ module AsanaExceptionNotifier
|
|
43
44
|
return unless io.respond_to?(:rewind)
|
44
45
|
io.rewind
|
45
46
|
io.read
|
46
|
-
rescue
|
47
|
-
io.inspect
|
48
47
|
end
|
49
48
|
|
50
49
|
def tempfile_details(tempfile)
|
@@ -120,8 +119,7 @@ module AsanaExceptionNotifier
|
|
120
119
|
end
|
121
120
|
|
122
121
|
def template_path_exist(path)
|
123
|
-
|
124
|
-
fail ArgumentError, "file #{path} doesn't exist"
|
122
|
+
File.exist?(path)
|
125
123
|
end
|
126
124
|
|
127
125
|
def get_hash_rows(hash, rows = [], prefix = '')
|
@@ -129,7 +127,7 @@ module AsanaExceptionNotifier
|
|
129
127
|
if value.is_a?(Hash)
|
130
128
|
get_hash_rows(value, rows, key)
|
131
129
|
else
|
132
|
-
rows.push(["#{prefix}#{key}".inspect, escape(
|
130
|
+
rows.push(["#{prefix}#{key}".inspect, escape(value.inspect)])
|
133
131
|
end
|
134
132
|
end
|
135
133
|
rows
|
@@ -143,9 +141,10 @@ module AsanaExceptionNotifier
|
|
143
141
|
text.gsub('&', '&').gsub('<', '<').gsub('>', '>')
|
144
142
|
end
|
145
143
|
|
146
|
-
def set_fieldset_key(links, prefix)
|
147
|
-
|
148
|
-
|
144
|
+
def set_fieldset_key(links, prefix, default)
|
145
|
+
prefix_name = prefix.present? ? prefix : default
|
146
|
+
links[prefix_name] ||= {}
|
147
|
+
prefix_name
|
149
148
|
end
|
150
149
|
|
151
150
|
def parse_fieldset_value(options)
|
@@ -153,6 +152,14 @@ module AsanaExceptionNotifier
|
|
153
152
|
value.is_a?(Hash) ? value.reject! { |_new_key, new_value| new_value.is_a?(Hash) } : value
|
154
153
|
end
|
155
154
|
|
155
|
+
def coerce_object_to_hash(object)
|
156
|
+
hash = {}
|
157
|
+
object.instance_variables.each do |name|
|
158
|
+
hash[name.to_s[1..-1]] = object.instance_variable_get(name)
|
159
|
+
end
|
160
|
+
hash
|
161
|
+
end
|
162
|
+
|
156
163
|
# Mount table for hash, using name and value and adding a name_value class
|
157
164
|
# to the generated table.
|
158
165
|
#
|
@@ -168,6 +175,19 @@ module AsanaExceptionNotifier
|
|
168
175
|
end.join(' ')
|
169
176
|
end
|
170
177
|
|
178
|
+
def remove_blank(args)
|
179
|
+
args.delete_if { |_key, value| value.blank? } if args.is_a?(Hash)
|
180
|
+
args.reject!(&:blank?) if args.is_a?(Array)
|
181
|
+
end
|
182
|
+
|
183
|
+
def get_table_headers(header)
|
184
|
+
header.map { |name| escape(name.to_s.humanize) }.join('</th><th>')
|
185
|
+
end
|
186
|
+
|
187
|
+
def get_table_rows(array)
|
188
|
+
array.map { |name| "<tr><td>#{name.join('</td><td>')}</td></tr>" }.join
|
189
|
+
end
|
190
|
+
|
171
191
|
# returns the root path of the gem
|
172
192
|
#
|
173
193
|
# @return [void]
|
@@ -13,16 +13,11 @@ module AsanaExceptionNotifier
|
|
13
13
|
# The first array is used as label.
|
14
14
|
#
|
15
15
|
def mount_table(array, options = {})
|
16
|
-
|
17
|
-
header = array.shift
|
18
|
-
|
19
|
-
header = header.map { |name| escape(name.to_s.humanize) }
|
20
|
-
rows = array.map { |name| "<tr><td>#{name.join('</td><td>')}</td></tr>" }
|
21
|
-
|
16
|
+
header = array.extract_options!
|
22
17
|
<<-HTML
|
23
18
|
<table #{hash_to_html_attributes(options)}>
|
24
|
-
<thead><tr><th>#{header
|
25
|
-
<tbody>#{
|
19
|
+
<thead><tr><th>#{get_table_headers(header)}</th></tr></thead>
|
20
|
+
<tbody>#{get_table_rows(array)}</tbody>
|
26
21
|
</table>
|
27
22
|
HTML
|
28
23
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: asana_exception_notifier
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- bogdanRada
|
@@ -419,6 +419,7 @@ files:
|
|
419
419
|
- lib/asana_exception_notifier.rb
|
420
420
|
- lib/asana_exception_notifier/classes/asana.rb
|
421
421
|
- lib/asana_exception_notifier/classes/error_page.rb
|
422
|
+
- lib/asana_exception_notifier/classes/unsafe_filter.rb
|
422
423
|
- lib/asana_exception_notifier/helpers/application_helper.rb
|
423
424
|
- lib/asana_exception_notifier/helpers/heredoc_helper.rb
|
424
425
|
- lib/asana_exception_notifier/initializers/zip.rb
|