Skip to content

Commit

Permalink
fix hub (#41)
Browse files Browse the repository at this point in the history
* reset the hub locations

* adding back overwritten changes

* Rerelease with correct fixes

* Adding missing things
  • Loading branch information
rajbos authored Dec 16, 2023
1 parent 4969764 commit 430b572
Show file tree
Hide file tree
Showing 8 changed files with 86 additions and 35 deletions.
Binary file added img/hub.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ Install from the marketplace: https://marketplace.visualstudio.com/items?itemNam

> Note: only project level dashboards are supported at the moment.
## Dashboard
This extension also adds a dashboard to the menu that shows the overall status of the entire project. All alerts from all repositories are loaded and shown in a single dashboard.
![Screenshot of the hub in action](/img/hub.png)

## Pipeline tasks
* Advanced-Security-Review: lets you check the pull request for newly introduced alerts from Dependency Scanning or Code Scanning (configurable). If new alerts are introduced, the task will fail.
> Note:
Expand Down
5 changes: 2 additions & 3 deletions vss-extension-dev.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"manifestVersion": 1,
"id": "GHAzDoWidget-DEV",
"version": "0.2.397",
"version": "0.2.404",
"public": false,
"name": "Advanced Security dashboard Widgets [DEV]",
"description": "[DEV] GitHub Advanced Security for Azure DevOps dashboard widgets",
Expand Down Expand Up @@ -221,11 +221,10 @@
"type": "ms.vss-web.hub",
"description": "[DEV] GHAzDO Hub",
"targets": [
"ms.vss-work-web.work-hub-group",
"ms.vss-code-web.code-hub-group"
],
"properties": {
"name": "Advanced Security Dashboard",
"name": "Advanced Security [DEV]",
"uri": "widgets/widgets/hub/hub.html",
"iconName": "Shield",
"order": 99
Expand Down
16 changes: 15 additions & 1 deletion vss-extension.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"manifestVersion": 1,
"id": "GHAzDoWidget",
"version": "0.0.1.14",
"version": "0.0.1.17",
"public": true,
"name": "Advanced Security dashboard Widgets",
"description": "GitHub Advanced Security for Azure DevOps dashboard widgets",
Expand Down Expand Up @@ -162,6 +162,20 @@
"uri": "widgets/widgets/chart/configuration_2x2.html"
}
},
{
"id": "GHAzDoWidget.Hub",
"type": "ms.vss-web.hub",
"description": "GHAzDO Hub",
"targets": [
"ms.vss-code-web.code-hub-group"
],
"properties": {
"name": "Advanced Security Dashboard",
"uri": "widgets/widgets/hub/hub.html",
"iconName": "Shield",
"order": 99
}
},
{
"id": "GHAzDoDependencyReviewTask",
"type": "ms.vss-distributed-task.task",
Expand Down
36 changes: 23 additions & 13 deletions widgets/library.js
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ async function storeAlerts(repoId, alertResult) {
}
}

async function getAlertsTrendLines(organization, projectName, repoId) {
async function getAlertsTrendLines(organization, projectName, repoId, daysToGoBack, summaryBucket) {
consoleLog(`getAlertsTrend for organization [${organization}], project [${projectName}], repo [${repoId}]`)
try {
alertResult = null
Expand All @@ -203,19 +203,29 @@ async function getAlertsTrendLines(organization, projectName, repoId) {
alertResult = await authenticatedGet(url)
//consoleLog('alertResult: ' + JSON.stringify(alertResult))
}
consoleLog('alertResult count: ' + alertResult.count)
if (alertResult) {
consoleLog('alertResult count: ' + alertResult.count)
}
else {
consoleLog('alertResult is null')
return {
secretAlertsTrend: [],
dependencyAlertsTrend: [],
codeAlertsTrend: []
}
}

// load the Secret alerts and create a trend line over the last 3 weeks
const secretAlerts = alertResult.value.filter(alert => alert.alertType === AlertType.SECRET.name)
const secretAlertsTrend = getAlertsTrendLine(secretAlerts, 'secret')
const secretAlertsTrend = getAlertsTrendLine(secretAlerts, AlertType.SECRET.name, daysToGoBack, summaryBucket)
consoleLog('')
// load the Dependency alerts and create a trend line over the last 3 weeks
const dependencyAlerts = alertResult.value.filter(alert => alert.alertType === AlertType.DEPENDENCY.name)
const dependencyAlertsTrend = getAlertsTrendLine(dependencyAlerts, 'dependency')
const dependencyAlertsTrend = getAlertsTrendLine(dependencyAlerts, AlertType.DEPENDENCY.name, daysToGoBack, summaryBucket)
consoleLog('')
// load the Code alerts and create a trend line over the last 3 weeks
const codeAlerts = alertResult.value.filter(alert => alert.alertType === AlertType.CODE.name)
const codeAlertsTrend = getAlertsTrendLine(codeAlerts, 'code')
const codeAlertsTrend = getAlertsTrendLine(codeAlerts, AlertType.CODE.name, daysToGoBack, summaryBucket)

return {
secretAlertsTrend: secretAlertsTrend,
Expand Down Expand Up @@ -248,16 +258,16 @@ function checkAlertActiveOnDate(alert, dateStr) {
return seenClosed;
}

function getAlertsTrendLine(alerts, type) {
function getAlertsTrendLine(alerts, type, daysToGoBack = 21, summaryBucket = 1) {
consoleLog(`getAlertsTrendLine for type ${type}`);

const trendLine = [];
const trendLineSimple = [];
const today = new Date();
const threeWeeksAgo = new Date();
threeWeeksAgo.setDate(today.getDate() - 21);
const startDate = new Date();
startDate.setDate(today.getDate() - daysToGoBack);

for (let d = threeWeeksAgo; d <= today; d.setDate(d.getDate() + 1)) {
for (let d = startDate; d <= today; d.setDate(d.getDate() + summaryBucket)) {
const date = new Date(d);
const dateStr = date.toISOString().split('T')[0];

Expand All @@ -275,13 +285,13 @@ function getAlertsTrendLine(alerts, type) {
return trendLineSimple;
}

function getDatePoints() {
function getDatePoints(daysToGoBack = 21, summaryBucket = 1) {
const trendDates = [];
const today = new Date();
const threeWeeksAgo = new Date();
threeWeeksAgo.setDate(today.getDate() - 21);
const startDate = new Date();
startDate.setDate(today.getDate() - daysToGoBack);

for (let d = threeWeeksAgo; d <= today; d.setDate(d.getDate() + 1)) {
for (let d = startDate; d <= today; d.setDate(d.getDate() + summaryBucket)) {
const date = new Date(d);
const dateStr = date.toISOString().split('T')[0];
trendDates.push(dateStr);
Expand Down
10 changes: 5 additions & 5 deletions widgets/widgets/chart/chart.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
async function createChart($container, chartService, alertTrendLines, widgetSize) {
async function createChart($container, chartService, alertTrendLines, widgetSize, daysToGoBack = 21, summaryBucket = 1) {

const datePoints = getDatePoints();
const datePoints = getDatePoints(daysToGoBack, summaryBucket);
var chartOptions = {
"hostOptions": {
"height": "290",
Expand Down Expand Up @@ -94,16 +94,16 @@ async function renderPieChart(organization, projectName, repoId, $container, cha
}
}

async function renderTrendLine(organization, projectName, repoId, $container, chartService, widgetSize) {
async function renderTrendLine(organization, projectName, repoId, $container, chartService, widgetSize, daysToGoBack = 21, summaryBucket = 1) {
consoleLog('renderTrendLine');
try {
// get the trend data for alerts first
const alertTrendLines = await getAlertsTrendLines(organization, projectName, repoId)
const alertTrendLines = await getAlertsTrendLines(organization, projectName, repoId, daysToGoBack, summaryBucket)
consoleLog('Dependencies AlertTrend: ' + JSON.stringify(alertTrendLines.dependencyAlertsTrend));
consoleLog('Code scanning AlertTrend: ' + JSON.stringify(alertTrendLines.codeAlertsTrend));
consoleLog('Secrets AlertTrend: ' + JSON.stringify(alertTrendLines.secretAlertsTrend));

createChart($container, chartService, alertTrendLines, widgetSize);
createChart($container, chartService, alertTrendLines, widgetSize, daysToGoBack, summaryBucket);
}
catch (err) {
consoleLog(`Error loading the alerts trend: ${err}`);
Expand Down
37 changes: 27 additions & 10 deletions widgets/widgets/hub/hub.html
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,18 @@
const organization = webContext.account.name
const projectId = project.id
// convert project.name to url encoding
const projectName = project.name.replace(/ /g, "%20").replace(/&/g, "%26")
const chartService = await Services.ChartsService.getService()

await createCharts({chartService, projectName, organization})
await createCharts({chartService, projectName: project.name, organization})

const debugging = document.getElementById('debugInfoCheckbox')
// wait at least 5 seconds before hiding the progress div
setTimeout(() => {
if (!debugging.checked) {
const progressDivContainer = document.getElementById('progressDivContainer')
progressDivContainer.style.display = 'none'
}
}, 5000)
}
consoleLog('VSS.require function')
try {
Expand All @@ -49,11 +57,8 @@
const project = webContext.project
const organization = webContext.account.name
const projectId = project.id
// convert project.name to url encoding
const projectName = project.name.replace(/ /g, "%20").replace(/&/g, "%26")

consoleLog('project id: ' + projectId)
consoleLog('project name: ' + projectName)
consoleLog('organization name: ' + organization)

// Get the header element
Expand All @@ -71,11 +76,13 @@
codeAlertCount: $(progressDivContainer).find('.codeAlertCount')[0]
}
const projects = await getProjects(VSS, Service, RestClient)
// filter the projects to only the current project
const currentProject = projects.filter(p => p.id === projectId)
consoleLog(`Found [${projects?.length}] projects`)
loadAllAlertsFromAllRepos(VSS, Service, GitWebApi, organization, projects, progressDiv, redrawCharts)
loadAllAlertsFromAllRepos(VSS, Service, GitWebApi, organization, currentProject, progressDiv, redrawCharts)

// create the empty charts
await createCharts({chartService, projectName, organization})
await createCharts({chartService, projectName: project.name, organization})

consoleLog('returning WidgetStatusHelper.Success()')
}
Expand All @@ -90,7 +97,11 @@
<div class="widget" id="progressDivContainer">
<div>
<div class="float" style="font-weight:600;font-size:larger;margin-right:7px;">Loading data</div>
<div class="loadingTitle float float-break"></div>
<div class="loadingTitle float margin-right:7px;"></div>
<div class="float float-break" style="margin-right:7px;">
<input type="checkbox" id="debugInfoCheckbox" name="debugInfoCheckbox" value="debugInfoCheckbox" unchecked>
<label for="debugInfoCheckbox">Show debugging</label>
</div>
</div>
<div>
<div id="debugInfo" class="float float-break" date-startTime=""></div>
Expand Down Expand Up @@ -123,11 +134,13 @@ <h3>Code</h3>
</div>
</div>

<div class="widget float">
<div class="widget trendlineWidget float float-break">
<h2 class="ghazdoTitle" id="TitleOverallTrend">Overall alert trend</h2>
<div id="ChartContainerOverallTrend"></div>
</div>

<div style="clear: both;"></div>

<div class="widget float">
<h2 class="ghazdoTitle" id="TitleOverallDependencyPie">Overall dependencies alert levels</h2>
<div id="ChartContainerOverallDependencyPie"></div>
Expand All @@ -151,12 +164,16 @@ <h2 class="ghazdoTitle" id="TitleOverallCodeScanningPie">Overall code scanning a
padding: 5px 5px 5px 5px;
}

.trendlineWidget {
width: 650px;
}

.region-headerBreadcrumb {
display: none;
}

#progressDivContainer {
width: 435px;
width: 440px;
}

.float {
Expand Down
13 changes: 10 additions & 3 deletions widgets/widgets/hub/hub.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ async function createCharts({chartService, projectName, organization}) {
alertType: 1,
repo: "All repos",
repoId: "-1",
widgetWidth: 4,
containerName: "ChartContainerOverallTrend",
titleName: "TitleOverallTrend"
}
Expand Down Expand Up @@ -79,12 +80,16 @@ async function createHubChart({chartService, organization, projectName, data}) {
columnSpan: 2
}

if (data.widgetWidth) {
chartSize.columnSpan = data.widgetWidth;
}

switch (chartType) {
case "2":
try {
const alertType = GetAlertTypeFromValue(alertTypeConfig)
if (titleElement) {
titleElement.textContent = `${alertType.display} Alerts by Severity`
titleElement.textContent = `${alertType.display} alerts by severity`
}
await renderPieChart(organization, projectName, repoId, containerElement, chartService, alertType, chartSize)
}
Expand All @@ -95,9 +100,11 @@ async function createHubChart({chartService, organization, projectName, data}) {
default:
try {
if (titleElement) {
titleElement.textContent = `Advanced Security Alerts Trend`
titleElement.textContent = `Advanced Security alerts trend for ${projectName}`
}
await renderTrendLine(organization, projectName, repoId, containerElement, chartService, chartSize)
const daysToGoBack = 26 * 7 // look back half a year in chunks that count up to today
const summaryBucket = 7
await renderTrendLine(organization, projectName, repoId, containerElement, chartService, chartSize, daysToGoBack, summaryBucket)
}
catch (err) {
consoleLog(`Error loading the alerts trend: ${err}`)
Expand Down

0 comments on commit 430b572

Please sign in to comment.