Skip to content

Commit

Permalink
SP-706 Adds local cryptography to SDK HTML report
Browse files Browse the repository at this point in the history
  • Loading branch information
agustingroh committed May 16, 2024
1 parent 0ebdbec commit c6452cb
Show file tree
Hide file tree
Showing 7 changed files with 192 additions and 38 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.

### [0.13.1](https://github.com/scanoss/scanoss.js/compare/v0.13.0...v0.13.1) (2024-05-15)

### [0.13.0](https://github.com/scanoss/scanoss.js/compare/v0.12.2...v0.13.0) (2024-05-13)

### [0.12.2](https://github.com/scanoss/scanoss.js/compare/v0.12.0...v0.12.2) (2024-05-10)
Expand Down
119 changes: 82 additions & 37 deletions assets/ReportHTMLTemplate/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -658,29 +658,61 @@ <h4>License obligations</h4>
</template>
</section>

<!-- cryptography -->
<section aria-labelledby="nav-cryptography-tab" class="tab-pane fade" id="nav-cryptography" role="tabpanel"
tabindex="0">
<table class="table main-table" id="table-cryptography">
<thead>
<tr>
<th>Component</th>
<th>Version</th>
<th>Cryptography</th>
</tr>
</thead>
<tbody>
</tbody>
</table>

<template id="tpl-cryptography-row">
<tr>
<td></td>
<td></td>
<td></td>
</tr>
</template>
</section>
<!-- cryptography -->
<section aria-labelledby="nav-cryptography-tab" class="tab-pane fade" id="nav-cryptography" role="tabpanel"
tabindex="0">
<nav>
<div class="nav nav-tabs" id="nav-tab-crypto" role="tablist">
<button aria-controls="pane-local-cryptography" class="nav-link visible active" aria-selected="false" data-bs-target="#pane-local-cryptography"
data-bs-toggle="tab" id="crypto-file-tab" role="tab" type="button">Files</button>
<button aria-controls="pane-component-cryptography" class="nav-link visible" aria-selected="true" data-bs-target="#pane-component-cryptography"
data-bs-toggle="tab" id="crypto-component-tab" role="tab" type="button">Components</button>
</div>
</nav>

<div class="tab-content" id="myTabContent">
<div class="tab-pane" id="pane-component-cryptography" aria-labelledby="crypto-component-tab" role="tabpanel" tabindex="0">
<table class="table main-table" id="table-cryptography" >
<thead>
<tr>
<th>Component</th>
<th>Version</th>
<th>Cryptography</th>
</tr>
</thead>
<tbody>
</tbody>
</table>

<template id="tpl-cryptography-row">
<tr>
<td></td>
<td></td>
<td></td>
</tr>
</template>
</div>
<div class="tab-pane active" id="pane-local-cryptography" role="tabpanel" aria-labelledby="crypto-file-tab" tabindex="0">
<table class="table main-table" id="table-local-cryptography">
<thead>
<tr>
<th>File</th>
<th>Cryptography</th>
</tr>
</thead>
<tbody>
</tbody>
</table>

<template id="tpl-local-cryptography-row">
<tr>
<td></td>
<td></td>
</tr>
</template>
</div>
</div>
</section>

<!-- quality -->
<section aria-labelledby="nav-quality-tab" class="tab-pane fade" id="nav-quality" role="tabpanel"
Expand Down Expand Up @@ -809,7 +841,8 @@ <h4>License obligations</h4>
renderDependenciesTable();
renderVulnerabilitiesTable();
renderCopyrightTable();
renderCryptographyTable();
renderComponentCryptographyTable();
renderLocalCryptographyTable();
renderQualityTable();
renderHealthTable();
}
Expand Down Expand Up @@ -842,7 +875,7 @@ <h4>License obligations</h4>
if (data.dependencies) showTab('nav-dependencies-tab');
if (data.vulnerabilities) showTab('nav-vulnerabilities-tab');
if (existVersionKey('copyrights', data.component)) showTab('nav-copyrights-tab');
if (existVersionKey('cryptography', data.component)) showTab('nav-cryptography-tab');
if (data.cryptography) showTab('nav-cryptography-tab');
if (existVersionKey('quality', data.component)) showTab('nav-quality-tab');
if (existComponentKey('health', data.component)) showTab('nav-health-tab');
}
Expand Down Expand Up @@ -1135,24 +1168,36 @@ <h4>License obligations</h4>
}
}

function renderCryptographyTable() {
function renderComponentCryptographyTable() {
const template = document.querySelector("#tpl-cryptography-row");
const table = document.querySelector("#table-cryptography tbody");

const { component: componentData } = data;
const { cryptography } = data;

if (!componentData) return false;
if (!cryptography && !cryptography.components) return false;

for (const compData of componentData) {
for (const version of compData.versions) {
if (!version.cryptography) continue
const clon = template.content.cloneNode(true);
clon.querySelector('td:nth-child(1)').innerHTML = compData.name;
clon.querySelector('td:nth-child(2)').innerHTML = version.version;
clon.querySelector('td:nth-child(3)').innerHTML = version.cryptography.map(e => `${e.algorithm} (${e.strength})`).join('');
for (const crypto of cryptography.components) {
const clon = template.content.cloneNode(true);
clon.querySelector('td:nth-child(1)').innerHTML = crypto.purl;
clon.querySelector('td:nth-child(2)').innerHTML = crypto.version;
clon.querySelector('td:nth-child(3)').innerHTML = crypto.algorithms.map(e => `${e.algorithm} (${e.strength})`).join(' - ');
table.appendChild(clon);
}
}

table.appendChild(clon);
}
function renderLocalCryptographyTable(){
const template = document.querySelector("#tpl-local-cryptography-row");
const table = document.querySelector("#table-local-cryptography tbody");

const { cryptography } = data;

if (!cryptography && !cryptography.files) return false;

for (const crypto of cryptography.files) {
const clon = template.content.cloneNode(true);
clon.querySelector('td:nth-child(1)').innerHTML = crypto.file;
clon.querySelector('td:nth-child(2)').innerHTML = crypto.algorithms.map(e => `${e.algorithm} (${e.strength})`).join(' - ');
table.appendChild(clon);
}
}

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "scanoss",
"version": "0.13.0",
"version": "0.13.1",
"description": "The SCANOSS JS package provides a simple, easy to consume module for interacting with SCANOSS APIs/Engine.",
"main": "build/main/index.js",
"typings": "build/main/index.d.ts",
Expand Down
6 changes: 6 additions & 0 deletions src/cli/commands/scan.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ import { DecompressionFilter } from '../../sdk/tree/Filters/DecompressionFilter'
import { DecompressionManager } from '../../sdk/Decompress/DecompressionManager';
import path from 'path';
import { LicenseObligationDataProvider } from '../../sdk/Report/DataLayer/DataProviders/LicenseObligationDataProvider';
import {
CryptographyDataProvider
} from '../../sdk/Report/DataLayer/DataProviders/CryptographyDataProvider';

export async function scanHandler(
rootPath: string,
Expand Down Expand Up @@ -192,6 +195,9 @@ export async function scanHandler(
scannersResults.dependencies
)
);

dataProviderManager.addDataProvider(new CryptographyDataProvider(null,scannersResults.scanner));

const report = new Report(dataProviderManager);
scannerResultsString = await report.getHTML();
}
Expand Down
21 changes: 21 additions & 0 deletions src/sdk/Report/DataLayer/DataLayerTypes.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
import {
CryptoAlgorithm,
ICryptoItem
} from '../../Cryptography/CryptographyTypes';
import { CryptoItem } from '../../Cryptography/Scanneable/CryptoItem';

/************* Component interface definition *************/
export interface ComponentDataLayer {
key: string; // purl[0]
Expand Down Expand Up @@ -43,6 +49,7 @@ export interface Health {
stars: number;
forks: number;
}

/************* Component interface definition *************/

/************* Dependency interface definition *************/
Expand Down Expand Up @@ -116,6 +123,19 @@ export interface SummaryDataLayer {
totalFiles: number;
}


export interface ComponentCryptography {
purl: string;
version: string;
algorithms: Array<CryptoAlgorithm>;
}

/*********************** Files ****************************/
export interface CryptographyDataLayer {
files: Array<CryptoItem>;
components: Array<ComponentCryptography>;
}

// Each layer is created to group by differents criteria.
export interface IDataLayers {
licenses: LicenseDataLayer[];
Expand All @@ -124,6 +144,7 @@ export interface IDataLayers {
dependencies: DependencyDataLayer[];
vulnerabilities: VulnerabilityDataLayer[];
summary: SummaryDataLayer;
cryptography: CryptographyDataLayer;
}

export interface DataProvider {
Expand Down
1 change: 1 addition & 0 deletions src/sdk/Report/DataLayer/DataProviderManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export class DataProviderManager {
summary: null,
licenses: null,
licensesObligations: null,
cryptography: null,
};

for (const layer of this.dataLayersProviders)
Expand Down
79 changes: 79 additions & 0 deletions src/sdk/Report/DataLayer/DataProviders/CryptographyDataProvider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import {
ComponentCryptography,
DataProvider,
IDataLayers
} from '../DataLayerTypes';
import {
ScannerComponent,
ScannerResults
} from '../../../scanner/ScannerTypes';
import { IDependencyResponse } from '../../../Dependencies/DependencyTypes';
import {
CryptoAlgorithm,
ICryptoItem
} from '../../../Cryptography/CryptographyTypes';

export class CryptographyDataProvider implements DataProvider {
private files: Array<ICryptoItem>;
private scanRawResults: ScannerResults;
private componentList: Array<ScannerComponent>;
constructor(files: Array<ICryptoItem>, scanRawResults: ScannerResults,) {
this.files = files;
this.scanRawResults = scanRawResults;
}
async getData():Promise<IDataLayers> {

if(!this.files && !this.scanRawResults) return <IDataLayers>{ cryptography: null }

this.componentList = Object.values(this.scanRawResults).flat();
this.componentList = this.componentList.filter(
(component) => component.id !== 'none'
);

const componentCryptography = this.getCrypto(this.componentList);

return <IDataLayers>{
cryptography:{
files: this.files,
components: componentCryptography,
}
}
}

private getCrypto(scanComponents: Array<ScannerComponent>):Array<ComponentCryptography> {
const componentCrypto = [];
scanComponents.forEach((c)=>{
if(c.cryptography.length > 0){
const crypto = {
purl: c.purl,
version: c.version,
algorithms: c.cryptography
}
componentCrypto.push(crypto);
}
});
return this.normalizeAlgorithms(componentCrypto)
}

private normalizeAlgorithms(crypto: Array<ComponentCryptography>):Array<ComponentCryptography> {
crypto.forEach((c)=>{
c.algorithms = this.removeRepeatedAlgorithms(c.algorithms);
})

return crypto;

}

private removeRepeatedAlgorithms(algorithms: Array<CryptoAlgorithm>):Array<CryptoAlgorithm> {
const algorithmsMapper = new Map<string, { algorithm: string, strength: string }>();
algorithms.forEach((a) => {
const algorithmToLowerCase = a.algorithm.toLowerCase();
algorithmsMapper.set(algorithmToLowerCase, {...a, algorithm: algorithmToLowerCase})
});
return Array.from(algorithmsMapper.values());
}

getLayerName(): string {
return '';
}
}

0 comments on commit c6452cb

Please sign in to comment.