rapid7/metasploit-framework

View on GitHub
tools/dev/report_generation/support_matrix/template.erb

Summary

Maintainability
Test Coverage
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Meterpreter Support matrix</title>
  <style>
      :root {
          --background-color-yes: green;
          --background-color-yes-highlight: #007a00;
          --background-color-no: red;
          --background-color-no-highlight: #d90000;
      }

      html {
      }

      table {
          border-collapse: collapse;
          border: 2px solid rgb(200, 200, 200);
          letter-spacing: 1px;
          font-size: 0.8rem;
      }

      thead, tr th:nth-child(1) {
          background: white;
          position: sticky;
          top: 0;
          border: none;
          outline: 2px solid rgb(200, 200, 200);
          z-index: 20;
      }

      .summary-row {
          background: white;
          position: sticky;
          top: 40px;
          border: none;
          outline: 1px solid rgb(200, 200, 200);
          z-index: 20;
      }

      .summary-row th:first-child::before, .toggle-extensions::before {
          content: '- '
      }

      td {
          text-align: center;
      }

      td, th {
          position: relative;
      }

      .yes {
          background-color: var(--background-color-yes);
      }

      .no {
          background-color: var(--background-color-no);
      }

      .highlight, .highlight th:nth-child(1) {
          background-color: #f3f3f3;
      }

      .highlight.yes, .highlight .yes {
          background-color: var(--background-color-yes-highlight);
      }

      .highlight.no, .highlight .no {
          background-color: var(--background-color-no-highlight);
      }

      td, th {
          border: 1px solid rgb(190, 190, 190);
          padding: 10px 20px;
      }

      tr th:nth-child(1) {
          position: sticky;
          top: 0;
          left: 0;
          z-index: 10;
      }

      .tooltip .tooltip-inner {
          text-align:left;
          max-width: 800px;
      }
  </style>
  <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
  <script src="https://cdn.jsdelivr.net/npm/popper.js@1.14.7/dist/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
  <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.3.1/dist/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
  <script>
      $(function () {
          var allClosed = false;

          function columnSelector(index) {
              return "tr :nth-child(" + (index + 1) + ")";
          }

          var addTableHighlights = function () {
              var columnIndex = $(this).index();
              $(this).parent().addClass("highlight");
              $(this).closest('table').find(columnSelector(columnIndex)).addClass('highlight');
          };

          var removeTableHighlights = function () {
              var columnIndex = $(this).index();
              $(this).parent().removeClass("highlight");
              $(this).closest('table').find(columnSelector(columnIndex)).removeClass('highlight');
          };

          var toggleAllExtensions = function () {
              var extensions = $(this).closest('table').find('.summary-row').nextUntil();
              allClosed = !allClosed;
              if (allClosed) {
                  extensions.hide();
              } else {
                  extensions.show();
              }
          };

          var toggleExtension = function () {
              $(this).closest('.summary-row').nextUntil().toggle();
          }

          // Table highlighting events
          $('table')
              .delegate('th, td', 'mouseover', addTableHighlights)
              .delegate('th, td', 'mouseleave', removeTableHighlights)
              .delegate('.toggle-extensions', 'mouseup', toggleAllExtensions)
              .delegate('.summary-row', 'mouseup', toggleExtension)

          // Tooltip handling
          $('[data-toggle="tooltip"]').tooltip();
      })
  </script>
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
        integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
</head>
<body>

<main>
  <table>
    <colgroup>
    </colgroup>

    <thead>
    <%- largest_column_length = table[:rows].flat_map { |row| row[:values] }.map { |values| values[0].size }.max %>
    <%- table[:columns].each.with_index do |column, column_index| -%>
      <%- if column_index == 0 -%>
        <th class="toggle-extensions" style="width: <%= largest_column_length + 4 %>ch">Meterpreter Feature</th>
      <%- else -%>
        <th style="white-space: nowrap;">
          <%= column[:heading] -%>
          <!-- cog icon -->
          <span data-toggle="tooltip" data-placement="bottom" data-html="true" title="<%= column[:metadata].map { |k,v| "#{k}=#{v}" }.join('<br />') %>">
            <svg xmlns="http://www.w3.org/2000/svg" height="1em" viewBox="0 0 512 512"><!--! Font Awesome Free 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M495.9 166.6c3.2 8.7 .5 18.4-6.4 24.6l-43.3 39.4c1.1 8.3 1.7 16.8 1.7 25.4s-.6 17.1-1.7 25.4l43.3 39.4c6.9 6.2 9.6 15.9 6.4 24.6c-4.4 11.9-9.7 23.3-15.8 34.3l-4.7 8.1c-6.6 11-14 21.4-22.1 31.2c-5.9 7.2-15.7 9.6-24.5 6.8l-55.7-17.7c-13.4 10.3-28.2 18.9-44 25.4l-12.5 57.1c-2 9.1-9 16.3-18.2 17.8c-13.8 2.3-28 3.5-42.5 3.5s-28.7-1.2-42.5-3.5c-9.2-1.5-16.2-8.7-18.2-17.8l-12.5-57.1c-15.8-6.5-30.6-15.1-44-25.4L83.1 425.9c-8.8 2.8-18.6 .3-24.5-6.8c-8.1-9.8-15.5-20.2-22.1-31.2l-4.7-8.1c-6.1-11-11.4-22.4-15.8-34.3c-3.2-8.7-.5-18.4 6.4-24.6l43.3-39.4C64.6 273.1 64 264.6 64 256s.6-17.1 1.7-25.4L22.4 191.2c-6.9-6.2-9.6-15.9-6.4-24.6c4.4-11.9 9.7-23.3 15.8-34.3l4.7-8.1c6.6-11 14-21.4 22.1-31.2c5.9-7.2 15.7-9.6 24.5-6.8l55.7 17.7c13.4-10.3 28.2-18.9 44-25.4l12.5-57.1c2-9.1 9-16.3 18.2-17.8C227.3 1.2 241.5 0 256 0s28.7 1.2 42.5 3.5c9.2 1.5 16.2 8.7 18.2 17.8l12.5 57.1c15.8 6.5 30.6 15.1 44 25.4l55.7-17.7c8.8-2.8 18.6-.3 24.5 6.8c8.1 9.8 15.5 20.2 22.1 31.2l4.7 8.1c6.1 11 11.4 22.4 15.8 34.3zM256 336a80 80 0 1 0 0-160 80 80 0 1 0 0 160z"/></svg>
          </span>
        </th>
      <%- end -%>
    <%- end -%>
    </tr>
    </thead>

    <%- table[:rows].each.with_index do |row, _row_index| -%>
      <tbody>
      <tr class="summary-row">
        <%- row[:heading].each.with_index do |value, value_index| -%>
          <%- if value_index == 0 -%>
            <th><%= value -%></th>
          <%- else -%>
            <th>
              <div class="progress">
                <div class="progress-bar" style="width: <%= value -%>"></div>
              </div>
              <%= value -%>
            </th>
          <%- end -%>
        <%- end -%>
      </tr>
      <%- row[:values].each do |row| -%>
        <tr style="display: none">
          <%- row.each.with_index do |value, cell_index| -%>
            <%- if cell_index == 0 -%>
              <th><%= value -%></th>
            <%- elsif value.is_a?(TrueClass) || value.is_a?(FalseClass) -%>
              <td class="<%= value ? 'yes' : 'no' %>"><%= value ? '&nbsp;' : '&nbsp;' -%></td>
            <%- else -%>
              <td><%= value -%></td>
            <%- end -%>
          <%- end -%>
        </tr>
      <%- end -%>
      </tbody>
    <%- end -%>
  </table>
</main>
</body>
</html>