From 3a2ce1d47d1d111c5afe9f7d1bfdd482ff256207 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 2 Aug 2021 17:50:32 -0300 Subject: [PATCH 01/16] =?UTF-8?q?Configurar=20Blazer=20para=20mostrar=20es?= =?UTF-8?q?tad=C3=ADsticas?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/application_controller.rb | 9 +++++++++ config/blazer.yml | 2 +- config/routes.rb | 7 +++---- db/migrate/20200206163257_install_blazer.rb | 2 -- 4 files changed, 13 insertions(+), 7 deletions(-) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index acd0134..f95159f 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -62,6 +62,15 @@ class ApplicationController < ActionController::Base render 'application/page_not_found', status: :not_found end + # Necesario para poder acceder a Blazer. Solo les usuaries de este + # sitio pueden acceder al panel. + def require_usuarie + unless find_site.usuarie? current_usuarie + redirect_to root_path + return + end + end + protected def configure_permitted_parameters diff --git a/config/blazer.yml b/config/blazer.yml index 2ba0965..11792ff 100644 --- a/config/blazer.yml +++ b/config/blazer.yml @@ -50,7 +50,7 @@ user_method: current_usuarie user_name: email # custom before_action to use for auth -# before_action_method: require_admin +before_action_method: require_usuarie # email to send checks from from_email: blazer@<%= ENV.fetch('SUTTY', 'sutty.nl') %> diff --git a/config/routes.rb b/config/routes.rb index 2c5f1c6..186dd66 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -4,8 +4,6 @@ Rails.application.routes.draw do devise_for :usuaries get '/.well-known/change-password', to: redirect('/usuaries/edit') - mount Blazer::Engine, at: 'blazer' - root 'application#index' constraints(Constraints::ApiSubdomain.new) do @@ -38,6 +36,9 @@ Rails.application.routes.draw do match '/api/v3/projects/:site_id/notices' => 'api/v1/notices#create', via: %i[post] resources :sites, constraints: { site_id: %r{[^/]+}, id: %r{[^/]+} } do + # Usar Blazer para mostrar estadísticas + mount Blazer::Engine, at: 'stats', as: 'stats' + # Gestionar actualizaciones del sitio get 'pull', to: 'sites#fetch' post 'pull', to: 'sites#merge' @@ -73,7 +74,5 @@ Rails.application.routes.draw do # Compilar el sitio post 'enqueue', to: 'sites#enqueue' post 'reorder_posts', to: 'sites#reorder_posts' - - resources :stats, only: [:index] end end diff --git a/db/migrate/20200206163257_install_blazer.rb b/db/migrate/20200206163257_install_blazer.rb index 9b08416..3279905 100644 --- a/db/migrate/20200206163257_install_blazer.rb +++ b/db/migrate/20200206163257_install_blazer.rb @@ -3,8 +3,6 @@ # Blazer class InstallBlazer < ActiveRecord::Migration[6.0] def change - return unless Rails.env.production? - create_table :blazer_queries do |t| t.references :creator t.string :name From 7511afbf88575fdc62265d0adfe02b56ac764eb6 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 2 Aug 2021 17:51:35 -0300 Subject: [PATCH 02/16] Les usuaries tienen consultas --- app/models/usuarie.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/models/usuarie.rb b/app/models/usuarie.rb index 6de7ba4..c88dcc6 100644 --- a/app/models/usuarie.rb +++ b/app/models/usuarie.rb @@ -11,6 +11,8 @@ class Usuarie < ApplicationRecord has_many :roles has_many :sites, through: :roles + has_many :blazer_audits, foreign_key: 'user_id', class_name: 'Blazer::Audit' + has_many :blazer_queries, foreign_key: 'creator_id', class_name: 'Blazer::Query' def name email.split('@', 2).first From ddc459130a45b9aa15a590bfa276218facb99030 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 2 Aug 2021 17:54:27 -0300 Subject: [PATCH 03/16] Acceder a la lista de consultas disponibles con la identidad de Sutty --- app/controllers/application_controller.rb | 7 +++++++ app/views/blazer/queries/home.haml | 9 +++++++++ app/views/layouts/_breadcrumb.haml | 2 +- app/views/layouts/blazer/application.haml | 14 ++++++++++++++ config/locales/en.yml | 6 ++++++ config/locales/es.yml | 6 ++++++ 6 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 app/views/blazer/queries/home.haml create mode 100644 app/views/layouts/blazer/application.haml diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index f95159f..2b5088f 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -69,6 +69,13 @@ class ApplicationController < ActionController::Base redirect_to root_path return end + + # Necesario para los breadcrumbs. + ActionView::Base.include Loaf::ViewExtensions unless ActionView::Base.included_modules.include? Loaf::ViewExtensions + + breadcrumb current_usuarie.email, main_app.edit_usuarie_registration_path + breadcrumb 'sites.index', main_app.sites_path, match: :exact + breadcrumb 'stats.index', root_path, match: :exact end protected diff --git a/app/views/blazer/queries/home.haml b/app/views/blazer/queries/home.haml new file mode 100644 index 0000000..325ba12 --- /dev/null +++ b/app/views/blazer/queries/home.haml @@ -0,0 +1,9 @@ +#queries + %table.table + %tbody.list + - @queries.each do |query| + %tr + -# + Por alguna razón no tenemos acceso a query_path para poder + generar la URL según Rails + %td= link_to query[:name], "/sites/#{params[:site_id]}/stats/queries/#{query[:to_param]}" diff --git a/app/views/layouts/_breadcrumb.haml b/app/views/layouts/_breadcrumb.haml index c4920bc..f209787 100644 --- a/app/views/layouts/_breadcrumb.haml +++ b/app/views/layouts/_breadcrumb.haml @@ -20,5 +20,5 @@ role: 'button', class: 'btn' %li.nav-item - = link_to t('.logout'), destroy_usuarie_session_path, + = link_to t('.logout'), main_app.destroy_usuarie_session_path, method: :delete, role: 'button', class: 'btn' diff --git a/app/views/layouts/blazer/application.haml b/app/views/layouts/blazer/application.haml new file mode 100644 index 0000000..add9419 --- /dev/null +++ b/app/views/layouts/blazer/application.haml @@ -0,0 +1,14 @@ +!!! +%html + %head + %meta{content: 'text/html; charset=UTF-8', 'http-equiv': 'Content-Type'}/ + %title= blazer_title ? blazer_title : 'Sutty' + %meta{charset: 'utf-8'}/ + = favicon_link_tag 'blazer/favicon.png' + = stylesheet_link_tag 'application' + = javascript_pack_tag 'blazer', 'data-turbolinks-track': 'reload' + = csrf_meta_tags + %body{ class: yield(:body) } + .container-fluid#sutty + = render 'layouts/breadcrumb' + = yield diff --git a/config/locales/en.yml b/config/locales/en.yml index fc194ea..7fd83f6 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -576,3 +576,9 @@ en: edit: 'Editing' usuaries: index: 'Users' + stats: + index: 'Statistics' + blazer: + queries: + show: + empty: '(empty)' diff --git a/config/locales/es.yml b/config/locales/es.yml index e818539..0a48742 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -584,3 +584,9 @@ es: edit: 'Editando' usuaries: index: 'Usuaries' + stats: + index: 'Estadísticas' + blazer: + queries: + show: + empty: '(vacío)' From 49e5603687af77ac18d20a1f2975baed18e98925 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 2 Aug 2021 17:57:40 -0300 Subject: [PATCH 04/16] Por cuidados, modificar Blazer pero no poder crear consultas --- app/controllers/concerns/blazer_decorator.rb | 44 ++++++++++++++++++++ config/application.rb | 7 ++++ 2 files changed, 51 insertions(+) create mode 100644 app/controllers/concerns/blazer_decorator.rb diff --git a/app/controllers/concerns/blazer_decorator.rb b/app/controllers/concerns/blazer_decorator.rb new file mode 100644 index 0000000..99b162e --- /dev/null +++ b/app/controllers/concerns/blazer_decorator.rb @@ -0,0 +1,44 @@ +# frozen_string_literal: true + +# Modificaciones para Blazer +module BlazerDecorator + # No poder obtener información de la base de datos. + module DisableDatabaseInfo + extend ActiveSupport::Concern + + included do + def docs; end + + def tables; end + + def schema; end + end + end + + # Deshabilitar edición de consultas y chequeos. + module DisableEdits + extend ActiveSupport::Concern + + included do + def create; end + + def update; end + + def destroy; end + + def run; end + + def refresh; end + + def cancel; end + end + end +end + +classes = [Blazer::QueriesController, Blazer::ChecksController, Blazer::DashboardsController] +modules = [BlazerDecorator::DisableDatabaseInfo, BlazerDecorator::DisableEdits] +classes.each do |klass| + modules.each do |modul| + klass.include modul unless klass.included_modules.include? modul + end +end diff --git a/config/application.rb b/config/application.rb index 7326ae0..5b6e373 100644 --- a/config/application.rb +++ b/config/application.rb @@ -38,6 +38,13 @@ module Sutty config.active_storage.variant_processor = :vips + config.to_prepare do + # Load application's model / class decorators + Dir.glob(File.join(File.dirname(__FILE__), '../app/**/*_decorator.rb')) do |c| + Rails.configuration.cache_classes ? require(c) : load(c) + end + end + config.after_initialize do ActiveStorage::DirectUploadsController.include ActiveStorage::AuthenticatedDirectUploadsController From 85ad518d8d4e92fe0254b43e8775b7c0f2b76830 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 2 Aug 2021 18:01:34 -0300 Subject: [PATCH 05/16] =?UTF-8?q?Correr=20Blazer=20sincr=C3=B3nicamente?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Deshabilitamos la funcionalidad asincrónica de Blazer porque ejecuta unos malabares extraños con JS, que filtran la consulta hacia el código. La idea es ejecutar consultas más livianas, con lo que por ahora no lo necesitamos. Podríamos recuperar esto usando ActionCable luego. Además, reimplementa la lógica de generación de gráficos en el controlador, para simplificar la vista. --- app/controllers/concerns/blazer_decorator.rb | 145 +++++++++++++++++++ app/views/blazer/queries/show.haml | 51 +++++++ package.json | 2 + yarn.lock | 35 ++++- 4 files changed, 232 insertions(+), 1 deletion(-) create mode 100644 app/views/blazer/queries/show.haml diff --git a/app/controllers/concerns/blazer_decorator.rb b/app/controllers/concerns/blazer_decorator.rb index 99b162e..f259857 100644 --- a/app/controllers/concerns/blazer_decorator.rb +++ b/app/controllers/concerns/blazer_decorator.rb @@ -33,6 +33,149 @@ module BlazerDecorator def cancel; end end end + + # Blazer hace un gran esfuerzo para ejecutar consultas de forma + # asincrónica pero termina enviándolas por JS. + module RunSync + extend ActiveSupport::Concern + + included do + alias_method :original_show, :show + + include Blazer::BaseHelper + + def show + original_show + + options = { user: blazer_user, query: @query, run_id: SecureRandom.uuid, async: false } + @data_source = Blazer.data_sources[@query.data_source] + @result = Blazer::RunStatement.new.perform(@data_source, @statement, options) + chart_data + end + + private + + # blazer-2.4.2/app/views/blazer/queries/run.html.erb + def chart_type + case @result.chart_type + when /\Aline(2)?\z/ + chart_options.merge! min: nil + when /\Abar(2)?\z/ + chart_options.merge! library: { tooltips: { intersect: false, axis: 'x' } } + when 'pie' + chart_options + when 'scatter' + chart_options.merge! library: { tooltips: { intersect: false } }, xtitle: @result.columns[0], + ytitle: @result.columns[1] + when nil + else + if @result.column_types.size == 2 + chart_options.merge! library: { tooltips: { intersect: false, axis: 'x' } } + else + chart_options.merge! library: { tooltips: { intersect: false } } + end + end + + @result.chart_type + end + + def chart_data + @chart_data ||= + case chart_type + when 'line' + @result.columns[1..-1].each_with_index.map do |k, i| + { + name: blazer_series_name(k), + data: @result.rows.map do |r| + [r[0], r[i + 1]] + end, + library: series_library[i] + } + end + when 'line2' + @result.rows.group_by do |r| + v = r[1] + (@result.boom[@result.columns[1]] || {})[v.to_s] || v + end.each_with_index.map do |(name, v), i| + { + name: blazer_series_name(name), + data: v.map do |v2| + [v2[0], v2[2]] + end, + library: series_library[i] + } + end + when 'pie' + @result.rows.map do |r| + [(@result.boom[@result.columns[0]] || {})[r[0].to_s] || r[0], r[1]] + end + when 'bar' + (@result.rows.first.size - 1).times.map do |i| + name = @result.columns[i + 1] + + { + name: blazer_series_name(name), + data: @result.rows.first(20).map do |r| + [(@result.boom[@result.columns[0]] || {})[r[0].to_s] || r[0], r[i + 1]] + end + } + end + when 'bar2' + first_20 = @result.rows.group_by { |r| r[0] }.values.first(20).flatten(1) + labels = first_20.map { |r| r[0] }.uniq + series = first_20.map { |r| r[1] }.uniq + labels.each do |l| + series.each do |s| + first_20 << [l, s, 0] unless first_20.find { |r| r[0] == l && r[1] == s } + end + end + + first_20.group_by do |r| + v = r[1] + (@result.boom[@result.columns[1]] || {})[v.to_s] || v + end.each_with_index.map do |(name, v), _i| + { + name: blazer_series_name(name), + data: v.sort_by do |r2| + labels.index(r2[0]) + end.map do |v2| + v3 = v2[0] + [(@result.boom[@result.columns[0]] || {})[v3.to_s] || v3, v2[2]] + end + } + end + when 'scatter' + @result.rows + end + end + + def target_index + @target_index ||= @result.columns.index do |k| + k.downcase == 'target' + end + end + + def series_library + @series_library ||= {}.tap do |sl| + if target_index + color = '#109618' + sl[target_index - 1] = { + pointStyle: 'line', + hitRadius: 5, + borderColor: color, + pointBackgroundColor: color, + backgroundColor: color, + pointHoverBackgroundColor: color + } + end + end + end + + def chart_options + @chart_options ||= { id: SecureRandom.hex } + end + end + end end classes = [Blazer::QueriesController, Blazer::ChecksController, Blazer::DashboardsController] @@ -42,3 +185,5 @@ classes.each do |klass| klass.include modul unless klass.included_modules.include? modul end end + +Blazer::QueriesController.include BlazerDecorator::RunSync diff --git a/app/views/blazer/queries/show.haml b/app/views/blazer/queries/show.haml new file mode 100644 index 0000000..5ec3da9 --- /dev/null +++ b/app/views/blazer/queries/show.haml @@ -0,0 +1,51 @@ +- blazer_title @query.name +.container + .row + .col-12 + %h1= @query.name + - if @query.description.present? + %p.lead= @query.description + - unless @result.chart_type.blank? + .col-12 + - case @result.chart_type + - when 'line' + = line_chart @chart_data, **@chart_options + - when 'line2' + = line_chart @chart_data, **@chart_options + - when 'pie' + = pie_chart @chart_data, **@chart_options + - when 'bar' + = column_chart @chart_data, **@chart_options + - when 'bar2' + = column_chart @chart_data, **@chart_options + - when 'scatter' + = scatter_chart @chart_data, **@chart_options + .col-12 + %table.table + %thead + %tr + - @result.columns.each do |key| + - next if key.include? 'ciphertext' + - next if key.include? 'encrypted' + %th.position-sticky.background-white= key + %tbody + - @result.rows.each do |row| + %tr + - row.each_with_index do |v, i| + - k = @result.columns[i] + - next if k.include? 'ciphertext' + - next if k.include? 'encrypted' + %td + - if v.is_a?(Time) + - v = blazer_time_value(@data_source, k, v) + + - unless v.nil? + - if v.is_a?(String) && v.empty? + %span.text-muted= t('.empty') + - elsif @data_source.linked_columns[k] + = link_to blazer_format_value(k, v), @data_source.linked_columns[k].gsub('{value}', u(v.to_s)), target: '_blank' + - else + = blazer_format_value(k, v) + + - if (v2 = (@result.boom[k] || {})[v.nil? ? v : v.to_s]) + %span.text-muted= v2 diff --git a/package.json b/package.json index 0a2458a..6340651 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,8 @@ "@rails/ujs": "^6.1.3-1", "@rails/webpacker": "5.2.1", "babel-loader": "^8.2.2", + "chart.js": "2.9.3", + "chartkick": "3.2.1", "circular-dependency-plugin": "^5.2.2", "commonmark": "^0.29.0", "fork-awesome": "^1.1.7", diff --git a/yarn.lock b/yarn.lock index 11ff78c..b478ff6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2119,6 +2119,34 @@ chalk@^4.1.0: ansi-styles "^4.1.0" supports-color "^7.1.0" +chart.js@2.9.3: + version "2.9.3" + resolved "https://registry.yarnpkg.com/chart.js/-/chart.js-2.9.3.tgz#ae3884114dafd381bc600f5b35a189138aac1ef7" + integrity sha512-+2jlOobSk52c1VU6fzkh3UwqHMdSlgH1xFv9FKMqHiNCpXsGPQa/+81AFa+i3jZ253Mq9aAycPwDjnn1XbRNNw== + dependencies: + chartjs-color "^2.1.0" + moment "^2.10.2" + +chartjs-color-string@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/chartjs-color-string/-/chartjs-color-string-0.6.0.tgz#1df096621c0e70720a64f4135ea171d051402f71" + integrity sha512-TIB5OKn1hPJvO7JcteW4WY/63v6KwEdt6udfnDE9iCAZgy+V4SrbSxoIbTw/xkUIapjEI4ExGtD0+6D3KyFd7A== + dependencies: + color-name "^1.0.0" + +chartjs-color@^2.1.0: + version "2.4.1" + resolved "https://registry.yarnpkg.com/chartjs-color/-/chartjs-color-2.4.1.tgz#6118bba202fe1ea79dd7f7c0f9da93467296c3b0" + integrity sha512-haqOg1+Yebys/Ts/9bLo/BqUcONQOdr/hoEr2LLTRl6C5LXctUdHxsCYfvQVg5JIxITrfCNUDr4ntqmQk9+/0w== + dependencies: + chartjs-color-string "^0.6.0" + color-convert "^1.9.3" + +chartkick@3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/chartkick/-/chartkick-3.2.1.tgz#a80c2005ae353c5ae011d0a756b6f592fc8fc7a9" + integrity sha512-zV0kUeZNqrX28AmPt10QEDXHKadbVFOTAFkCMyJifHzGFkKzGCDXxVR8orZ0fC1HbePzRn5w6kLCOVxDQbMUCg== + chokidar@^2.1.8: version "2.1.8" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917" @@ -2238,7 +2266,7 @@ collection-visit@^1.0.0: map-visit "^1.0.0" object-visit "^1.0.0" -color-convert@^1.9.0, color-convert@^1.9.1: +color-convert@^1.9.0, color-convert@^1.9.1, color-convert@^1.9.3: version "1.9.3" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== @@ -5005,6 +5033,11 @@ mkdirp@^1.0.3, mkdirp@^1.0.4: resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== +moment@^2.10.2: + version "2.29.1" + resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.1.tgz#b2be769fa31940be9eeea6469c075e35006fa3d3" + integrity sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ== + move-concurrently@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92" From 75e6b7a8014ea83362e126dc85dcd681c053514d Mon Sep 17 00:00:00 2001 From: f Date: Mon, 2 Aug 2021 18:25:42 -0300 Subject: [PATCH 06/16] =?UTF-8?q?Agregar=20los=20helpers=20de=20Devise=20t?= =?UTF-8?q?ambi=C3=A9n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Para que tengamos `current_usuarie` dentro de las vistas de Blazer. --- app/controllers/application_controller.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 2b5088f..efe1a4a 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -71,7 +71,9 @@ class ApplicationController < ActionController::Base end # Necesario para los breadcrumbs. - ActionView::Base.include Loaf::ViewExtensions unless ActionView::Base.included_modules.include? Loaf::ViewExtensions + [Loaf::ViewExtensions, Devise::Controllers::UrlHelpers].each do |helper_module| + ActionView::Base.include helper_module unless ActionView::Base.included_modules.include? helper_module + end breadcrumb current_usuarie.email, main_app.edit_usuarie_registration_path breadcrumb 'sites.index', main_app.sites_path, match: :exact From 841279f6cf81d545f064e94dc3aab39e7d2cc454 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 2 Aug 2021 18:31:17 -0300 Subject: [PATCH 07/16] =?UTF-8?q?fixup!=20Agregar=20los=20helpers=20de=20D?= =?UTF-8?q?evise=20tambi=C3=A9n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/application_controller.rb | 4 +--- app/views/layouts/_breadcrumb.haml | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index efe1a4a..2b5088f 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -71,9 +71,7 @@ class ApplicationController < ActionController::Base end # Necesario para los breadcrumbs. - [Loaf::ViewExtensions, Devise::Controllers::UrlHelpers].each do |helper_module| - ActionView::Base.include helper_module unless ActionView::Base.included_modules.include? helper_module - end + ActionView::Base.include Loaf::ViewExtensions unless ActionView::Base.included_modules.include? Loaf::ViewExtensions breadcrumb current_usuarie.email, main_app.edit_usuarie_registration_path breadcrumb 'sites.index', main_app.sites_path, match: :exact diff --git a/app/views/layouts/_breadcrumb.haml b/app/views/layouts/_breadcrumb.haml index f209787..dc0e315 100644 --- a/app/views/layouts/_breadcrumb.haml +++ b/app/views/layouts/_breadcrumb.haml @@ -12,7 +12,7 @@ - else %span.line-clamp-1= link_to crumb.name, crumb.url - - if current_usuarie + - if @current_usuarie || current_usuarie %ul.navbar-nav - if @site&.tienda? %li.nav-item From af67c39dc477581fb6a0acd2adce5aacb683d0aa Mon Sep 17 00:00:00 2001 From: f Date: Mon, 2 Aug 2021 18:37:15 -0300 Subject: [PATCH 08/16] Agregar el nombre del sitio en la miga de pan --- app/controllers/application_controller.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 2b5088f..c9e5a99 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -65,7 +65,8 @@ class ApplicationController < ActionController::Base # Necesario para poder acceder a Blazer. Solo les usuaries de este # sitio pueden acceder al panel. def require_usuarie - unless find_site.usuarie? current_usuarie + site = find_site + unless site.usuarie? current_usuarie redirect_to root_path return end @@ -75,6 +76,7 @@ class ApplicationController < ActionController::Base breadcrumb current_usuarie.email, main_app.edit_usuarie_registration_path breadcrumb 'sites.index', main_app.sites_path, match: :exact + breadcrumb site.title, main_app.site_path(site), match: :exact breadcrumb 'stats.index', root_path, match: :exact end From 44450da5208b55582c2ff287c538d71a452da274 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 2 Aug 2021 18:41:09 -0300 Subject: [PATCH 09/16] Les usuaries solo pueden ver sus propias consultas. --- app/controllers/concerns/blazer_decorator.rb | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/controllers/concerns/blazer_decorator.rb b/app/controllers/concerns/blazer_decorator.rb index f259857..eee0db6 100644 --- a/app/controllers/concerns/blazer_decorator.rb +++ b/app/controllers/concerns/blazer_decorator.rb @@ -55,6 +55,11 @@ module BlazerDecorator private + # Solo mostrar las consultas de le usuarie + def set_queries(_) + @queries = (@current_usuarie || current_usuarie).blazer_queries + end + # blazer-2.4.2/app/views/blazer/queries/run.html.erb def chart_type case @result.chart_type From 6f08ca6c36b1297d93bd7ba435e5e7d70b930a60 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 3 Aug 2021 10:10:30 -0300 Subject: [PATCH 10/16] =?UTF-8?q?A=20veces=20se=20pasa=20el=20par=C3=A1met?= =?UTF-8?q?ro=20en=20set=5Fqueries?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/concerns/blazer_decorator.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/concerns/blazer_decorator.rb b/app/controllers/concerns/blazer_decorator.rb index eee0db6..876f423 100644 --- a/app/controllers/concerns/blazer_decorator.rb +++ b/app/controllers/concerns/blazer_decorator.rb @@ -56,7 +56,7 @@ module BlazerDecorator private # Solo mostrar las consultas de le usuarie - def set_queries(_) + def set_queries(_ = nil) @queries = (@current_usuarie || current_usuarie).blazer_queries end From 489cbb414ccd4a7fbd5c81f7e6051838a4512ada Mon Sep 17 00:00:00 2001 From: f Date: Tue, 3 Aug 2021 10:15:48 -0300 Subject: [PATCH 11/16] Ya no usamos un hash de queries --- app/views/blazer/queries/home.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/blazer/queries/home.haml b/app/views/blazer/queries/home.haml index 325ba12..977b6bd 100644 --- a/app/views/blazer/queries/home.haml +++ b/app/views/blazer/queries/home.haml @@ -6,4 +6,4 @@ -# Por alguna razón no tenemos acceso a query_path para poder generar la URL según Rails - %td= link_to query[:name], "/sites/#{params[:site_id]}/stats/queries/#{query[:to_param]}" + %td= link_to query[:name], "/sites/#{params[:site_id]}/stats/queries/#{query.to_param}" From e87fad33eae8b1225d090a9e6f5464933c69dea6 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 3 Aug 2021 10:16:26 -0300 Subject: [PATCH 12/16] =?UTF-8?q?La=20tabla=20se=20puede=20scrollear=20y?= =?UTF-8?q?=20mantiene=20los=20t=C3=ADtulos?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/blazer/queries/show.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/blazer/queries/show.haml b/app/views/blazer/queries/show.haml index 5ec3da9..3b2beed 100644 --- a/app/views/blazer/queries/show.haml +++ b/app/views/blazer/queries/show.haml @@ -27,7 +27,7 @@ - @result.columns.each do |key| - next if key.include? 'ciphertext' - next if key.include? 'encrypted' - %th.position-sticky.background-white= key + %th.position-sticky.background-white{ style: 'top: 0' }= key %tbody - @result.rows.each do |row| %tr From 71ff9e5e7b22013b5c4f033518871ea9670d52c5 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 3 Aug 2021 10:24:18 -0300 Subject: [PATCH 13/16] =?UTF-8?q?Traducir=20columnas=20o=20mostrarlas=20co?= =?UTF-8?q?mo=20t=C3=ADtulos?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Los nombres más comunas de columnas se pueden agregar al archivo de traducción, si la traducción no existe se convierte a un título. ```ruby "total_horas".titleize => "Total Horas" ``` --- app/views/blazer/queries/show.haml | 2 +- config/locales/en.yml | 5 +++++ config/locales/es.yml | 5 +++++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/app/views/blazer/queries/show.haml b/app/views/blazer/queries/show.haml index 3b2beed..3b5cb15 100644 --- a/app/views/blazer/queries/show.haml +++ b/app/views/blazer/queries/show.haml @@ -27,7 +27,7 @@ - @result.columns.each do |key| - next if key.include? 'ciphertext' - next if key.include? 'encrypted' - %th.position-sticky.background-white{ style: 'top: 0' }= key + %th.position-sticky.background-white{ style: 'top: 0' }= t("blazer.columns.#{key}", default: key.titleize) %tbody - @result.rows.each do |row| %tr diff --git a/config/locales/en.yml b/config/locales/en.yml index 7fd83f6..18faa8b 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -579,6 +579,11 @@ en: stats: index: 'Statistics' blazer: + columns: + total: 'Total' + dia: 'Date' + date: 'Date' + visitas: 'Visits' queries: show: empty: '(empty)' diff --git a/config/locales/es.yml b/config/locales/es.yml index 0a48742..5229a59 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -587,6 +587,11 @@ es: stats: index: 'Estadísticas' blazer: + columns: + total: 'Total' + dia: 'Fecha' + date: 'Fecha' + visitas: 'Visitas' queries: show: empty: '(vacío)' From 71436d3be49cb3d0cdde8e37338369f10fdaf81f Mon Sep 17 00:00:00 2001 From: f Date: Wed, 4 Aug 2021 12:17:49 -0300 Subject: [PATCH 14/16] =?UTF-8?q?Usar=20el=20sistema=20de=20autorizaci?= =?UTF-8?q?=C3=B3n=20de=20Sutty?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Y eliminar código sin utilizar. --- app/controllers/application_controller.rb | 9 ++++----- app/controllers/posts_controller.rb | 3 --- app/controllers/private_controller.rb | 2 -- app/controllers/sites_controller.rb | 3 --- app/controllers/stats_controller.rb | 18 ------------------ app/models/{site_stat.rb => site_blazer.rb} | 2 +- app/policies/site_blazer_policy.rb | 10 ++++++++++ app/policies/site_stat_policy.rb | 15 --------------- 8 files changed, 15 insertions(+), 47 deletions(-) delete mode 100644 app/controllers/stats_controller.rb rename app/models/{site_stat.rb => site_blazer.rb} (50%) create mode 100644 app/policies/site_blazer_policy.rb delete mode 100644 app/policies/site_stat_policy.rb diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index c9e5a99..d849821 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -3,6 +3,7 @@ # Forma de ingreso a Sutty class ApplicationController < ActionController::Base include ExceptionHandler + include Pundit protect_from_forgery with: :null_session, prepend: true @@ -10,6 +11,7 @@ class ApplicationController < ActionController::Base before_action :configure_permitted_parameters, if: :devise_controller? around_action :set_locale + rescue_from Pundit::NilPolicyError, with: :page_not_found rescue_from ActionController::RoutingError, with: :page_not_found rescue_from ActionController::ParameterMissing, with: :page_not_found @@ -33,7 +35,7 @@ class ApplicationController < ActionController::Base def find_site id = params[:site_id] || params[:id] - unless (site = current_usuarie.sites.find_by_name(id)) + unless (site = current_usuarie&.sites&.find_by_name(id)) raise SiteNotFound end @@ -66,10 +68,7 @@ class ApplicationController < ActionController::Base # sitio pueden acceder al panel. def require_usuarie site = find_site - unless site.usuarie? current_usuarie - redirect_to root_path - return - end + authorize SiteBlazer.new(site) # Necesario para los breadcrumbs. ActionView::Base.include Loaf::ViewExtensions unless ActionView::Base.included_modules.include? Loaf::ViewExtensions diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb index 3ef2672..448592d 100644 --- a/app/controllers/posts_controller.rb +++ b/app/controllers/posts_controller.rb @@ -2,9 +2,6 @@ # Controlador para artículos class PostsController < ApplicationController - include Pundit - rescue_from Pundit::NilPolicyError, with: :page_not_found - before_action :authenticate_usuarie! # TODO: Traer los comunes desde ApplicationController diff --git a/app/controllers/private_controller.rb b/app/controllers/private_controller.rb index bb4d782..01b6888 100644 --- a/app/controllers/private_controller.rb +++ b/app/controllers/private_controller.rb @@ -6,8 +6,6 @@ class PrivateController < ApplicationController # XXX: Permite ejecutar JS skip_forgery_protection - include Pundit - # Enviar el archivo si existe, agregar una / al final siempre para no # romper las direcciones relativas. def show diff --git a/app/controllers/sites_controller.rb b/app/controllers/sites_controller.rb index bdaa901..b482622 100644 --- a/app/controllers/sites_controller.rb +++ b/app/controllers/sites_controller.rb @@ -2,9 +2,6 @@ # Controlador de sitios class SitesController < ApplicationController - include Pundit - rescue_from Pundit::NilPolicyError, with: :page_not_found - before_action :authenticate_usuarie! breadcrumb -> { current_usuarie.email }, :edit_usuarie_registration_path diff --git a/app/controllers/stats_controller.rb b/app/controllers/stats_controller.rb deleted file mode 100644 index 07baaf1..0000000 --- a/app/controllers/stats_controller.rb +++ /dev/null @@ -1,18 +0,0 @@ -# frozen_string_literal: true - -# Estadísticas del sitio -class StatsController < ApplicationController - include Pundit - before_action :authenticate_usuarie! - - def index - @site = find_site - authorize SiteStat.new(@site) - - # Solo queremos el promedio de tiempo de compilación, no de - # instalación de dependencias. - stats = @site.build_stats.jekyll - @build_avg = stats.average(:seconds).to_f.round(2) - @build_max = stats.maximum(:seconds).to_f.round(2) - end -end diff --git a/app/models/site_stat.rb b/app/models/site_blazer.rb similarity index 50% rename from app/models/site_stat.rb rename to app/models/site_blazer.rb index 73503ac..76dee12 100644 --- a/app/models/site_stat.rb +++ b/app/models/site_blazer.rb @@ -1,3 +1,3 @@ # frozen_string_literal: true -SiteStat = Struct.new(:site) +SiteBlazer = Struct.new(:site) diff --git a/app/policies/site_blazer_policy.rb b/app/policies/site_blazer_policy.rb new file mode 100644 index 0000000..a6ea01b --- /dev/null +++ b/app/policies/site_blazer_policy.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +# Les invitades no pueden ver las estadísticas (aun) +SiteBlazerPolicy = Struct.new(:usuarie, :site_blazer) do + def home? + site_blazer&.site&.usuarie? usuarie + end + + alias_method :show?, :home? +end diff --git a/app/policies/site_stat_policy.rb b/app/policies/site_stat_policy.rb deleted file mode 100644 index a797034..0000000 --- a/app/policies/site_stat_policy.rb +++ /dev/null @@ -1,15 +0,0 @@ -# frozen_string_literal: true - -# Política de acceso a las estadísticas -class SiteStatPolicy - attr_reader :site_stat, :usuarie - - def initialize(usuarie, site_stat) - @usuarie = usuarie - @site_stat = site_stat - end - - def index? - site_stat.site.usuarie? usuarie - end -end From 249b115af848f02fb11dd1bbebd55c3a31f5fa28 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 4 Aug 2021 20:16:56 -0300 Subject: [PATCH 15/16] No enviar URLs en los chequeos. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Necesita más trabajo hacer esto y no tenemos un uso inmediato para chequeos específicos de sitios. fixes #2331 --- .../blazer/check_mailer/failing_checks.haml | 5 ++++ .../blazer/check_mailer/state_change.haml | 30 +++++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 app/views/blazer/check_mailer/failing_checks.haml create mode 100644 app/views/blazer/check_mailer/state_change.haml diff --git a/app/views/blazer/check_mailer/failing_checks.haml b/app/views/blazer/check_mailer/failing_checks.haml new file mode 100644 index 0000000..8624ae9 --- /dev/null +++ b/app/views/blazer/check_mailer/failing_checks.haml @@ -0,0 +1,5 @@ +%ul + - @checks.each do |check| + %li + = link_to check.query.name + = check.state diff --git a/app/views/blazer/check_mailer/state_change.haml b/app/views/blazer/check_mailer/state_change.haml new file mode 100644 index 0000000..48418a5 --- /dev/null +++ b/app/views/blazer/check_mailer/state_change.haml @@ -0,0 +1,30 @@ +!!! +%html + %head + %meta{:content => "text/html; charset=UTF-8", "http-equiv" => "Content-Type"}/ + %body{:style => "font-family: 'Helvetica Neue', Arial, Helvetica; font-size: 14px; color: #333;"} + - if @error + %p= @error + - elsif @rows_count > 0 && @check_type == "bad_data" + %p + - if @rows_count <= 10 + = pluralize(@rows_count, "row") + - else + Showing 10 of #{@rows_count} rows + %table{:style => "width: 100%; border-spacing: 0; border-collapse: collapse;"} + %thead + %tr + - @columns.first(5).each do |column| + %th{:style => "padding: 8px; line-height: 1.4; text-align: left; vertical-align: bottom; border-bottom: 2px solid #ddd; width: #{(100 / @columns.size).round(2)}%;"} + = column + %tbody + - @rows.first(10).each do |row| + %tr + - @columns.first(5).each_with_index do |column, i| + %td{:style => "padding: 8px; line-height: 1.4; vertical-align: top; border-top: 1px solid #ddd;"} + - value = row[i] + - if @column_types[i] == "time" && value.to_s.length > 10 + - value = Time.parse(value).in_time_zone(Blazer.time_zone) rescue value + = value + - if @columns.size > 5 + %p{:style => "color: #999;"} Only first 5 columns shown From 5885dd7e9615288bbe36cf0b413c3aeda042853e Mon Sep 17 00:00:00 2001 From: f Date: Fri, 6 Aug 2021 17:47:27 -0300 Subject: [PATCH 16/16] fixup! No enviar URLs en los chequeos. --- app/views/blazer/check_mailer/failing_checks.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/blazer/check_mailer/failing_checks.haml b/app/views/blazer/check_mailer/failing_checks.haml index 8624ae9..c28c393 100644 --- a/app/views/blazer/check_mailer/failing_checks.haml +++ b/app/views/blazer/check_mailer/failing_checks.haml @@ -1,5 +1,5 @@ %ul - @checks.each do |check| %li - = link_to check.query.name + = check.query.name = check.state