blazer 2.1.0 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of blazer might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d30135b6a6bfd6aa1bc940afff2c6e58ba3a4fec00a5e6cf4c34573acadc08ef
4
- data.tar.gz: 925787073e4b0f161ab974875ba7df666c3bc6cd99d87f93052a0a54e4b94663
3
+ metadata.gz: dac159313b83f05cfa2b39da88d889b08e0089a75047a6aff43c24d735b86eb2
4
+ data.tar.gz: e1d3594c4e957f04ffa575ce1aac36abf29586c275a2c402c2da5b9401356c57
5
5
  SHA512:
6
- metadata.gz: 245b6001c927c3c592afd6aaed930e11a35bdb56c39c165c5f4b318ce095b17937c25dc71efcf0b0cdca5a1a2c7139ad0f917903d429a228cafd9ab86d24c1d2
7
- data.tar.gz: afc5184b13e8ee2537b16b81f75a3ba703d357999dea851c887596b3daaf92a1bd486c1825129f15c93a72e6f23c16f5cc4d306c11346344ba560085e6ec5861
6
+ metadata.gz: 05a6d614fd96a40526f0ef7bb34cf6207a48e7bcdb6495f7ea925bec919c116918ad721d388e856c388d6746033fd184eadf25ca93a4afb9c541a8ab8758f8e1
7
+ data.tar.gz: 79e9087b9e4015cd866fe2b382f0bb015c104af05f9c8b1c209ce2aa06713a46436e2aa307a9901bf0d31fec861463f1224b0cc610d76e2dd5c9c12aa40a8807
data/CHANGELOG.md CHANGED
@@ -1,6 +1,12 @@
1
+ ## 2.2.0
2
+
3
+ - Added schema to table preview for Postgres and Redshift
4
+ - Fixed bug with Slack notifications not sending
5
+ - Dropped support for Rails 4.2
6
+
1
7
  ## 2.1.0
2
8
 
3
- - Fixed XSS vulnerability due to Chartkick - see [#245](https://github.com/ankane/blazer/issues/245)
9
+ - Require latest Chartkick to prevent possible XSS - see [#245](https://github.com/ankane/blazer/issues/245)
4
10
 
5
11
  ## 2.0.2
6
12
 
@@ -2,13 +2,9 @@ module Blazer
2
2
  class BaseController < ApplicationController
3
3
  # skip filters
4
4
  filters = _process_action_callbacks.map(&:filter) - [:activate_authlogic]
5
- if Rails::VERSION::MAJOR >= 5
6
- skip_before_action(*filters, raise: false)
7
- skip_after_action(*filters, raise: false)
8
- skip_around_action(*filters, raise: false)
9
- else
10
- skip_action_callback(*filters)
11
- end
5
+ skip_before_action(*filters, raise: false)
6
+ skip_after_action(*filters, raise: false)
7
+ skip_around_action(*filters, raise: false)
12
8
 
13
9
  protect_from_forgery with: :exception
14
10
 
@@ -1,6 +1,6 @@
1
1
  module Blazer
2
2
  class Audit < Record
3
- belongs_to :user, Blazer::BELONGS_TO_OPTIONAL.merge(class_name: Blazer.user_class.to_s)
4
- belongs_to :query, Blazer::BELONGS_TO_OPTIONAL
3
+ belongs_to :user, optional: true, class_name: Blazer.user_class.to_s
4
+ belongs_to :query, optional: true
5
5
  end
6
6
  end
@@ -1,6 +1,6 @@
1
1
  module Blazer
2
2
  class Check < Record
3
- belongs_to :creator, Blazer::BELONGS_TO_OPTIONAL.merge(class_name: Blazer.user_class.to_s) if Blazer.user_class
3
+ belongs_to :creator, optional: true, class_name: Blazer.user_class.to_s if Blazer.user_class
4
4
  belongs_to :query
5
5
 
6
6
  validates :query_id, presence: true
@@ -67,8 +67,8 @@ module Blazer
67
67
  end
68
68
 
69
69
  # do not notify on creation, except when not passing
70
- if (state_was != "new" || state != "passing") && state != state_was && emails.present?
71
- Blazer::CheckMailer.state_change(self, state, state_was, result.rows.size, message, result.columns, result.rows.first(10).as_json, result.column_types, check_type).deliver_now
70
+ if (state_was != "new" || state != "passing") && state != state_was
71
+ Blazer::CheckMailer.state_change(self, state, state_was, result.rows.size, message, result.columns, result.rows.first(10).as_json, result.column_types, check_type).deliver_now if emails.present?
72
72
  Blazer::SlackNotifier.state_change(self, state, state_was, result.rows.size, message, check_type)
73
73
  end
74
74
  save! if changed?
@@ -1,6 +1,6 @@
1
1
  module Blazer
2
2
  class Dashboard < Record
3
- belongs_to :creator, Blazer::BELONGS_TO_OPTIONAL.merge(class_name: Blazer.user_class.to_s) if Blazer.user_class
3
+ belongs_to :creator, optional: true, class_name: Blazer.user_class.to_s if Blazer.user_class
4
4
  has_many :dashboard_queries, dependent: :destroy
5
5
  has_many :queries, through: :dashboard_queries
6
6
 
@@ -1,6 +1,6 @@
1
1
  module Blazer
2
2
  class Query < Record
3
- belongs_to :creator, Blazer::BELONGS_TO_OPTIONAL.merge(class_name: Blazer.user_class.to_s) if Blazer.user_class
3
+ belongs_to :creator, optional: true, class_name: Blazer.user_class.to_s if Blazer.user_class
4
4
  has_many :checks, dependent: :destroy
5
5
  has_many :dashboard_queries, dependent: :destroy
6
6
  has_many :dashboards, through: :dashboard_queries
@@ -132,7 +132,12 @@
132
132
  this.tablesXhr = $.getJSON(Routes.tables_queries_path({data_source: this.dataSource}), function(data) {
133
133
  var newOptions = []
134
134
  for (var i = 0; i < data.length; i++) {
135
- newOptions.push({text: data[i], value: data[i]})
135
+ var table = data[i]
136
+ if (typeof table === "object") {
137
+ newOptions.push({text: table.table, value: table.value})
138
+ } else {
139
+ newOptions.push({text: table, value: table})
140
+ }
136
141
  }
137
142
  selectize.clearOptions()
138
143
  selectize.addOption(newOptions)
@@ -13,10 +13,7 @@
13
13
  <thead>
14
14
  <tr>
15
15
  <th colspan="2">
16
- <%= table[:table] %>
17
- <% if table[:schema] != "public" %>
18
- <span class="text-muted" style="font-weight: normal;"><%= table[:schema] %></span>
19
- <% end %>
16
+ <% if table[:schema] != "public" %><%= table[:schema] %>.<% end %><%= table[:table] %>
20
17
  </th>
21
18
  </tr>
22
19
  </thead>
data/lib/blazer.rb CHANGED
@@ -72,8 +72,6 @@ module Blazer
72
72
  "system requested abort", # redshift
73
73
  "maximum statement execution time exceeded" # mysql
74
74
  ]
75
- BELONGS_TO_OPTIONAL = {}
76
- BELONGS_TO_OPTIONAL[:optional] = true if Rails::VERSION::MAJOR >= 5
77
75
 
78
76
  def self.time_zone=(time_zone)
79
77
  @time_zone = time_zone.is_a?(ActiveSupport::TimeZone) ? time_zone : ActiveSupport::TimeZone[time_zone.to_s]
@@ -26,9 +26,8 @@ module Blazer
26
26
 
27
27
  result = select_all("#{statement} /*#{comment}*/")
28
28
  columns = result.columns
29
- cast_method = Rails::VERSION::MAJOR < 5 ? :type_cast : :cast_value
30
29
  result.rows.each do |untyped_row|
31
- rows << (result.column_types.empty? ? untyped_row : columns.each_with_index.map { |c, i| untyped_row[i] ? result.column_types[c].send(cast_method, untyped_row[i]) : untyped_row[i] })
30
+ rows << (result.column_types.empty? ? untyped_row : columns.each_with_index.map { |c, i| untyped_row[i] ? result.column_types[c].send(:cast_value, untyped_row[i]) : untyped_row[i] })
32
31
  end
33
32
  end
34
33
  rescue => e
@@ -41,19 +40,35 @@ module Blazer
41
40
  end
42
41
 
43
42
  def tables
44
- result = data_source.run_statement(connection_model.send(:sanitize_sql_array, ["SELECT table_name FROM information_schema.tables WHERE table_schema IN (?) ORDER BY table_name", schemas]), refresh_cache: true)
45
- result.rows.map(&:first)
43
+ sql = add_schemas("SELECT table_schema, table_name FROM information_schema.tables")
44
+ result = data_source.run_statement(sql, refresh_cache: true)
45
+ if postgresql? || redshift?
46
+ result.rows.sort_by { |r| [r[0] == default_schema ? "" : r[0], r[1]] }.map do |row|
47
+ table =
48
+ if row[0] == default_schema
49
+ row[1]
50
+ else
51
+ "#{row[0]}.#{row[1]}"
52
+ end
53
+
54
+ {
55
+ table: table,
56
+ value: connection_model.connection.quote_table_name(table)
57
+ }
58
+ end
59
+ else
60
+ result.rows.map(&:second).sort
61
+ end
46
62
  end
47
63
 
48
64
  def schema
49
- result = data_source.run_statement(connection_model.send(:sanitize_sql_array, ["SELECT table_schema, table_name, column_name, data_type, ordinal_position FROM information_schema.columns WHERE table_schema IN (?) ORDER BY 1, 2", schemas]))
50
- result.rows.group_by { |r| [r[0], r[1]] }.map { |k, vs| {schema: k[0], table: k[1], columns: vs.sort_by { |v| v[2] }.map { |v| {name: v[2], data_type: v[3]} }} }
65
+ sql = add_schemas("SELECT table_schema, table_name, column_name, data_type, ordinal_position FROM information_schema.columns")
66
+ result = data_source.run_statement(sql)
67
+ result.rows.group_by { |r| [r[0], r[1]] }.map { |k, vs| {schema: k[0], table: k[1], columns: vs.sort_by { |v| v[2] }.map { |v| {name: v[2], data_type: v[3]} }} }.sort_by { |t| [t[:schema] == default_schema ? "" : t[:schema], t[:table]] }
51
68
  end
52
69
 
53
70
  def preview_statement
54
- if postgresql?
55
- "SELECT * FROM \"{table}\" LIMIT 10"
56
- elsif sqlserver?
71
+ if sqlserver?
57
72
  "SELECT TOP (10) * FROM {table}"
58
73
  else
59
74
  "SELECT * FROM {table} LIMIT 10"
@@ -92,9 +107,9 @@ module Blazer
92
107
 
93
108
  def cancel(run_id)
94
109
  if postgresql?
95
- select_all("SELECT pg_cancel_backend(pid) FROM pg_stat_activity WHERE pid <> pg_backend_pid() AND query LIKE '%,run_id:#{run_id}%'")
110
+ select_all("SELECT pg_cancel_backend(pid) FROM pg_stat_activity WHERE pid <> pg_backend_pid() AND query LIKE ?", ["%,run_id:#{run_id}%"])
96
111
  elsif redshift?
97
- first_row = select_all("SELECT pid FROM stv_recents WHERE status = 'Running' AND query LIKE '%,run_id:#{run_id}%'").first
112
+ first_row = select_all("SELECT pid FROM stv_recents WHERE status = 'Running' AND query LIKE ?", ["%,run_id:#{run_id}%"]).first
98
113
  if first_row
99
114
  select_all("CANCEL #{first_row["pid"].to_i}")
100
115
  end
@@ -107,7 +122,8 @@ module Blazer
107
122
 
108
123
  protected
109
124
 
110
- def select_all(statement)
125
+ def select_all(statement, params = [])
126
+ statement = connection_model.send(:sanitize_sql_array, [statement] + params) if params.any?
111
127
  connection_model.connection.select_all(statement)
112
128
  end
113
129
 
@@ -137,18 +153,28 @@ module Blazer
137
153
  connection_model.connection.adapter_name rescue nil
138
154
  end
139
155
 
140
- def schemas
141
- settings["schemas"] || [connection_model.connection_config[:schema] || default_schema]
156
+ def default_schema
157
+ @default_schema ||= begin
158
+ if postgresql? || redshift?
159
+ "public"
160
+ elsif sqlserver?
161
+ "dbo"
162
+ else
163
+ connection_model.connection_config[:database]
164
+ end
165
+ end
142
166
  end
143
167
 
144
- def default_schema
145
- if postgresql? || redshift?
146
- "public"
147
- elsif sqlserver?
148
- "dbo"
168
+ def add_schemas(query)
169
+ if settings["schemas"]
170
+ where = "table_schema IN (?)"
171
+ schemas = settings["schemas"]
149
172
  else
150
- connection_model.connection_config[:database]
173
+ where = "table_schema NOT IN (?)"
174
+ schemas = ["information_schema"]
175
+ schemas << "pg_catalog" if postgresql? || redshift?
151
176
  end
177
+ connection_model.send(:sanitize_sql_array, ["#{query} WHERE #{where}", schemas])
152
178
  end
153
179
 
154
180
  def set_timeout(timeout)
@@ -1,3 +1,3 @@
1
1
  module Blazer
2
- VERSION = "2.1.0"
2
+ VERSION = "2.2.0"
3
3
  end
@@ -1,25 +1,10 @@
1
- # taken from https://github.com/collectiveidea/audited/blob/master/lib/generators/audited/install_generator.rb
2
- require "rails/generators"
3
- require "rails/generators/migration"
4
- require "active_record"
5
1
  require "rails/generators/active_record"
6
2
 
7
3
  module Blazer
8
4
  module Generators
9
5
  class InstallGenerator < Rails::Generators::Base
10
- include Rails::Generators::Migration
11
-
12
- source_root File.expand_path("../templates", __FILE__)
13
-
14
- # Implement the required interface for Rails::Generators::Migration.
15
- def self.next_migration_number(dirname) #:nodoc:
16
- next_migration_number = current_migration_number(dirname) + 1
17
- if ActiveRecord::Base.timestamped_migrations
18
- [Time.now.utc.strftime("%Y%m%d%H%M%S"), "%.14d" % next_migration_number].max
19
- else
20
- "%.3d" % next_migration_number
21
- end
22
- end
6
+ include ActiveRecord::Generators::Migration
7
+ source_root File.join(__dir__, "templates")
23
8
 
24
9
  def copy_migration
25
10
  migration_template "install.rb", "db/migrate/install_blazer.rb", migration_version: migration_version
@@ -30,9 +15,7 @@ module Blazer
30
15
  end
31
16
 
32
17
  def migration_version
33
- if ActiveRecord::VERSION::MAJOR >= 5
34
- "[#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}]"
35
- end
18
+ "[#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}]"
36
19
  end
37
20
  end
38
21
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: blazer
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.0
4
+ version: 2.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Kane
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-06-04 00:00:00.000000000 Z
11
+ date: 2019-07-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: railties
@@ -16,28 +16,28 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '4.2'
19
+ version: '5'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '4.2'
26
+ version: '5'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: activerecord
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '4.2'
33
+ version: '5'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: '4.2'
40
+ version: '5'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: chartkick
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -214,14 +214,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
214
214
  requirements:
215
215
  - - ">="
216
216
  - !ruby/object:Gem::Version
217
- version: '2.3'
217
+ version: '2.4'
218
218
  required_rubygems_version: !ruby/object:Gem::Requirement
219
219
  requirements:
220
220
  - - ">="
221
221
  - !ruby/object:Gem::Version
222
222
  version: '0'
223
223
  requirements: []
224
- rubygems_version: 3.0.3
224
+ rubygems_version: 3.0.4
225
225
  signing_key:
226
226
  specification_version: 4
227
227
  summary: Explore your data with SQL. Easily create charts and dashboards, and share