Browse Source

SVG and DIV solutions to display grades infos

Norore 4 months ago
parent
commit
dccd6da7ad
  1. 2
      app/controllers/statistics_controller.rb
  2. 1
      app/javascript/js/stats/index.js
  3. 78
      app/views/statistics/index.html.erb
  4. 5
      bin/stats
  5. 4
      db/schema.rb

2
app/controllers/statistics_controller.rb

@ -5,7 +5,7 @@ class StatisticsController < ApplicationController
service = params.fetch :id
respond_to do |format|
format.json do
json = Stat.where(name: "grades_for_#{service}").order(date: :desc).first.dataset
json = Stat.where(name: "grades_for_#{service}").order(date: :desc).first.data
render json: json, status: :ok
end
end

1
app/javascript/js/stats/index.js

@ -54,6 +54,7 @@ document.addEventListener("DOMContentLoaded", () => {
fetch(`/statistics/${service}.json`).then((response) => {
if (response.status === 200) {
response.json().then((data) => {
console.info(data)
const labels = ["A+", "A", "B+", "B", "C+", "C", "D", "E", "F", "G"]
const dataset = JSON.parse(JSON.stringify(data, labels, 0))
chart.data.labels = labels

78
app/views/statistics/index.html.erb

@ -1,15 +1,79 @@
<div class="row">
<!-- <div class="col-4">-->
<!-- <h2>Requests per service</h2>-->
<!-- <canvas id="servicesChart" aria-label="Pie chart for number of requests per service" role="img"></canvas>-->
<!-- </div>-->
<% colors = {
"A+" => '#5cb85c',
"A" => '#5cb85c',
"B+" => '#8db457',
"B" => '#8db457',
"C+" => '#beb052',
"C" => '#beb052',
"D" => '#6c757d',
"E" => '#f0ad4e',
"F" => '#e4804e',
"G" => '#d9534f' } %>
<% %i[https smtp tls xmpp].each do |s| %>
<div class="col-6">
<h2>Grades for service <%= s.to_s.upcase %></h2>
<% %i[https smtp tls xmpp].each do |service| %>
<div>
<h2>Grades for service <%= service.to_s.upcase %></h2>
<canvas id="<%= "grades" + s.to_s.upcase_first + "Chart" %>" aria-label="Bar chart for number of grades for service <%= s.to_s.upcase %>" role="img"></canvas>
<% grades = Stat.where(name: "grades_for_#{service}").order(date: :desc).first
total = grades.data.collect { _2 }.sum %>
Over <%= total %> URL tested with a grade.<br>
<!-- SVG solution -->
<em>SVG solution</em>
<div class="row">
<svg width="100%" height="45" role="img" xmlns="http://www.w3.org/2000/svg" aria-labelledby="<%= "title-grades-#{service} description-grades-#{service}" %>">
<title id="<%= "title-grades-#{service}" %>">Last grades for service <%= service %></title>
<description id="<%= "description-grades-#{service}" %>">
This graphic represents the percentage of different grades obtained for the last analysis of
service <%= service %> requested. The obtained grades are:
<% grades.data.sort_by(&:first).each do |grade, number| %>
<% unless %w(T V).include?(grade)
percent = (number.to_f / total.to_f) * 100.0 %>
<%= "#{grade}: #{percent.round(2)} (#{number} requests)" %>;
<% end
end %>
Exotic grades like T or V are excluded from this graphic.
</description>
<% y = 0
x = 0
grades.data.sort_by(&:first).each do |grade, number|
%>
<% unless %w(T V).include?(grade) %>
<% percent = (number.to_f / total.to_f) * 100.0
color = colors[grade] %>
<rect x="<%= x %>%" y="<%= y %>" width="<%= "#{percent.round}%" %>"
height="40" style="<%= "fill:#{color};" %>"
data-service="<%= service %>"
data-grade="<%= grade %>"
data-percent="<%= "#{percent}%" %>"
data-number="<%= number %>"
/>
<text x="<%= x + 0.4 %>%" y="25" style="fill:black;"><%= "#{grade}: #{percent.round}% (#{number})" %></text>
<% x += percent.round %>
<% end
end %>
</svg>
</div>
<!-- DIV solution -->
<em>DIV solution</em>
<div class="row">
<% grades.data.sort_by(&:first).each do |grade, number| %>
<% unless %w(T V).include?(grade)
percent = (number.to_f / total.to_f) * 100.0
color = colors[grade] %>
<div style="width: <%= percent.round %>%; height: 2rem; line-height: 2rem; display: inline-block; background-color: <%= color %>; white-space: nowrap; text-overflow: ellipsis; margin-right: 2px">
<%= "#{grade}: #{percent.round}% (#{number})" %>
</div>
<% end
end %>
</div>
<% end %>
</div>
</div>
<% end %>

5
bin/stats

@ -18,7 +18,7 @@ class Analysis
return :ssl if %i[SSLv2 SSLv3].any? { protocols.include? _1 }
return :tls unless protocols.include? :TLSv1_2
return :tls1_2 unless protocols == %i[TLSv1_2]
return :tls1_2_only
:tls1_2_only
end
def ciphers
@ -49,14 +49,13 @@ class Analysis
return :no_pfs unless ciphers.include? true
return :pfs unless ciphers == [true]
return :pfs_only
:pfs_only
end
end
services = Analysis.group(:service).count
Stat.create! :request_per_service, services
# grade per service for https, smtp, tls and xmpp
%i[https smtp tls xmpp].each do |service|
services = Analysis.where service: service, pending: false

4
db/schema.rb

@ -15,7 +15,7 @@ ActiveRecord::Schema[7.0].define(version: 2022_03_26_181216) do
enable_extension "pgcrypto"
enable_extension "plpgsql"
create_table "analyses", id: :uuid, default: -> { "public.gen_random_uuid()" }, force: :cascade do |t|
create_table "analyses", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
t.string "service", null: false
t.string "host", null: false
t.boolean "pending", default: true, null: false
@ -30,7 +30,7 @@ ActiveRecord::Schema[7.0].define(version: 2022_03_26_181216) do
t.string "name"
t.date "date"
t.jsonb "data"
t.index ["name", "date"], name: "index_stats_on_name_and_date", unique: true
t.index ["name"], name: "index_stats_on_name"
end
end

Loading…
Cancel
Save