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 acd0134d..f95159f4 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 2ba0965f..11792ff1 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 2c5f1c60..186dd66f 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 9b084169..32799053 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 6de7ba4b..c88dcc68 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 f95159f4..2b5088f7 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 00000000..325ba121 --- /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 c4920bc7..f209787c 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 00000000..add94190 --- /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 fc194eab..7fd83f63 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 e8185391..0a48742a 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 00000000..99b162e6 --- /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 7326ae0f..5b6e373c 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 99b162e6..f2598573 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 00000000..5ec3da98 --- /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 0a2458a6..6340651f 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 11ff78cb..b478ff67 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 2b5088f7..efe1a4a3 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 efe1a4a3..2b5088f7 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 f209787c..dc0e3158 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 2b5088f7..c9e5a999 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 f2598573..eee0db64 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 eee0db64..876f423d 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 325ba121..977b6bda 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 5ec3da98..3b2beed6 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 3b2beed6..3b5cb152 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 7fd83f63..18faa8bb 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 0a48742a..5229a591 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 c9e5a999..d8498218 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 3ef26720..448592de 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 bb4d782d..01b6888c 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 bdaa9011..b4826226 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 07baaf1a..00000000 --- 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 73503aca..76dee12a 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 00000000..a6ea01b7 --- /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 a797034c..00000000 --- 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 00000000..8624ae9b --- /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 00000000..48418a58 --- /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 8624ae9b..c28c3936 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