Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle sast tool not found #71

Merged
merged 9 commits into from
May 3, 2024
2 changes: 1 addition & 1 deletion src/branchprotection/BranchProtectionService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export class BranchProtectionService {
if (error.status === 401) {
core.info('Failed to get branch protection');
// Removes link to REST API endpoint
const errorMessage: string = error.message.split('.')[0];
const errorMessage: string = error.message.split('-')[0];
core.warning(errorMessage, {
title: 'Branch protection control failed',
});
Expand Down
2 changes: 1 addition & 1 deletion src/identitiesInRepo/identitiesInRepoService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,11 @@

for await (const { data: page } of iterator) {
for (const user of page) {
if (user.permissions!.admin) {

Check warning on line 36 in src/identitiesInRepo/identitiesInRepoService.ts

View workflow job for this annotation

GitHub Actions / build

Forbidden non-null assertion
numberOfAdmins++;
} else if (user.permissions!.maintain!) {

Check warning on line 38 in src/identitiesInRepo/identitiesInRepoService.ts

View workflow job for this annotation

GitHub Actions / build

Forbidden non-null assertion

Check warning on line 38 in src/identitiesInRepo/identitiesInRepoService.ts

View workflow job for this annotation

GitHub Actions / build

Forbidden non-null assertion
numberOfWriters++;
} else if (user.permissions!.push!) {

Check warning on line 40 in src/identitiesInRepo/identitiesInRepoService.ts

View workflow job for this annotation

GitHub Actions / build

Forbidden non-null assertion
numberOfWriters++;
} else if (user.permissions!.triage!) {
numberOfReaders++;
Expand All @@ -56,7 +56,7 @@
core.info('Failed to fetch identities for repo');
if (error.status === 401 || error.status === 403) {
// Removes link to REST API endpoint
const errorMessage: string = error.message.split('.')[0];
const errorMessage: string = error.message.split('-')[0];
core.warning(errorMessage, {
title: 'Failed to fetch identities for repo',
});
Expand Down
14 changes: 8 additions & 6 deletions src/sasttools/CodeQLService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,12 @@ import GitHub_Tool_Severity_Level from '../types/GithubToolSeverityLevel';
import { CodeScanningAlertsForRepoResponseDataType } from '../types/OctokitResponses';

export class CodeQLService {
public static async setCodeQLFindings(octokit: Octokit, owner: string, repo: string): Promise<void> {
public static async setCodeQLFindings(
nameOfTool: string,
octokit: Octokit,
owner: string,
repo: string
): Promise<void> {
try {
// https://www.npmjs.com/package/octokit#pagination
const iterator: AsyncIterableIterator<CodeScanningAlertsForRepoResponseDataType> = octokit.paginate.iterator(
Expand Down Expand Up @@ -49,6 +54,7 @@ export class CodeQLService {
console.log('High: ' + sastNumberOfSeverity3);
console.log('Critical: ' + sastNumberOfSeverity4);

core.exportVariable('sastTool', nameOfTool);
core.exportVariable('SASTnumberOfSeverity1', sastNumberOfSeverity1);
core.exportVariable('SASTnumberOfSeverity2', sastNumberOfSeverity2);
core.exportVariable('SASTnumberOfSeverity3', sastNumberOfSeverity3);
Expand All @@ -57,7 +63,7 @@ export class CodeQLService {
core.info('Failed to get CodeQL severities');
if (error.status === 401 || error.status === 403 || error.status === 404) {
// Removes link to REST API endpoint
const errorMessage: string = error.message.split('.')[0];
const errorMessage: string = error.message.split('-')[0];
core.warning(errorMessage, {
title: 'SAST tool control failed',
});
Expand All @@ -66,10 +72,6 @@ export class CodeQLService {
title: 'SAST tool control failed',
});
}
core.exportVariable('SASTnumberOfSeverity1', 0);
core.exportVariable('SASTnumberOfSeverity2', 0);
core.exportVariable('SASTnumberOfSeverity3', 0);
core.exportVariable('SASTnumberOfSeverity4', 0);
}
}
}
14 changes: 8 additions & 6 deletions src/sasttools/SastService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,18 @@ export class SastService {
if (process.env.sastTool) {
sast = process.env.sastTool;
}
console.log(`Tool:`, `${sast}`);
core.exportVariable('sastTool', sast);

if (!sast || sast === '' || sast === 'name-of-tool') {
core.warning('SAST Tool is not set!');
return;
}

if (sast.toLowerCase() === GitHub_Tools.CODEQL.toLowerCase()) {
await CodeQLService.setCodeQLFindings(octokit, owner, repo);
console.log(`Tool:`, `${sast}`);
switch (sast.toLowerCase()) {
case GitHub_Tools.CODEQL.toLowerCase():
await CodeQLService.setCodeQLFindings(sast, octokit, owner, repo);
break;
default:
core.exportVariable('sastTool', sast);
break;
}
console.log();
}
Expand Down
14 changes: 8 additions & 6 deletions src/scatools/DependabotService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,12 @@ import GitHub_Tool_Severity_Level from '../types/GithubToolSeverityLevel';
import { DependabotAlertsForRepoResponseDataType } from '../types/OctokitResponses';

export class DependabotService {
public static async setDependabotFindings(octokit: Octokit, owner: string, repo: string): Promise<void> {
public static async setDependabotFindings(
nameOfTool: string,
octokit: Octokit,
owner: string,
repo: string
): Promise<void> {
try {
// https://www.npmjs.com/package/octokit#pagination
const iterator: AsyncIterableIterator<DependabotAlertsForRepoResponseDataType> = octokit.paginate.iterator(
Expand Down Expand Up @@ -46,6 +51,7 @@ export class DependabotService {
console.log('High: ' + scaNumberOfSeverity3);
console.log('Critical: ' + scaNumberOfSeverity4);

core.exportVariable('scaTool', nameOfTool);
core.exportVariable('SCAnumberOfSeverity1', scaNumberOfSeverity1);
core.exportVariable('SCAnumberOfSeverity2', scaNumberOfSeverity2);
core.exportVariable('SCAnumberOfSeverity3', scaNumberOfSeverity3);
Expand All @@ -54,7 +60,7 @@ export class DependabotService {
core.info('Failed to get Dependabot severities');
if (error.status === 401 || error.status === 403 || error.status === 404) {
// Removes link to REST API endpoint
const errorMessage: string = error.message.split('.')[0];
const errorMessage: string = error.message.split('-')[0];
core.warning(errorMessage, {
title: 'SCA tool control failed',
});
Expand All @@ -63,10 +69,6 @@ export class DependabotService {
title: 'SCA tool control failed',
});
}
core.exportVariable('SCAnumberOfSeverity1', 0);
core.exportVariable('SCAnumberOfSeverity2', 0);
core.exportVariable('SCAnumberOfSeverity3', 0);
core.exportVariable('SCAnumberOfSeverity4', 0);
}
}
}
14 changes: 8 additions & 6 deletions src/scatools/ScaService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,18 @@ export class ScaService {
if (process.env.scaTool) {
sca = process.env.scaTool;
}
console.log(`Tool:`, `${sca}`);
core.exportVariable('scaTool', sca);

if (!sca || sca === '' || sca === 'name-of-tool') {
core.warning('SCA Tool is not set!');
return;
}

if (sca.toLowerCase() === GitHub_Tools.DEPENDABOT.toLowerCase()) {
await DependabotService.setDependabotFindings(octokit, owner, repo);
console.log(`Tool:`, `${sca}`);
switch (sca.toLowerCase()) {
case GitHub_Tools.DEPENDABOT.toLowerCase():
await DependabotService.setDependabotFindings(sca, octokit, owner, repo);
break;
default:
core.exportVariable('scaTool', sca);
break;
}
console.log();
}
Expand Down
4 changes: 2 additions & 2 deletions src/secretscanning/SecretScanningService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,13 @@ export class SecretScanningService {
core.info('Failed to get number of exposed secrets');
if (error.status === 401) {
// Removes link to REST API endpoint
const errorMessage: string = error.message.split('.')[0];
const errorMessage: string = error.message.split('-')[0];
core.warning(errorMessage, {
title: 'Number of exposed secrets control failed',
});
} else if (error.status === 404) {
// Removes link to REST API endpoint
const errorMessage: string = error.message.split('.')[0];
const errorMessage: string = error.message.split('-')[0];
if (errorMessage === 'Secret scanning is disabled on this repository') {
core.warning(errorMessage, {
title: 'Number of exposed secrets control failed',
Expand Down
18 changes: 9 additions & 9 deletions tests/BranchProtectionService.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import * as core from '@actions/core';
import sinon, { SinonStub } from 'sinon';
import { BranchProtectionService } from '../src/branchprotection/BranchProtectionService';

describe('BranchProtectionService', () => {
describe('BranchProtectionService', function () {
let warningStub: SinonStub;
let noticeStub: SinonStub;
let infoStub: SinonStub;
Expand All @@ -19,7 +19,7 @@ describe('BranchProtectionService', () => {
},
};

beforeEach(() => {
beforeEach(function () {
warningStub = sinon.stub(core, 'warning');
noticeStub = sinon.stub(core, 'notice');
infoStub = sinon.stub(core, 'info');
Expand All @@ -28,11 +28,11 @@ describe('BranchProtectionService', () => {
getBranchProtectionStub = sinon.stub(octokitMock.rest.repos, 'getBranchProtection');
});

afterEach(() => {
afterEach(function () {
sinon.restore();
});

it('should handle successful branch protection retrieval', async () => {
it('should handle successful branch protection retrieval', async function () {
getBranchProtectionStub.returns({
data: {
enforce_admins: { enabled: true },
Expand All @@ -45,7 +45,7 @@ describe('BranchProtectionService', () => {
sinon.assert.notCalled(warningStub);
});

it('should warn when admins can bypass branch protection rules', async () => {
it('should warn when admins can bypass branch protection rules', async function () {
getBranchProtectionStub.returns({
data: {
enforce_admins: { enabled: false },
Expand All @@ -58,7 +58,7 @@ describe('BranchProtectionService', () => {
sinon.assert.calledOnceWithExactly(exportVariableStub, 'numberOfReviewers', 0);
});

it('should handle a 401 error', async () => {
it('should handle a 401 error', async function () {
getBranchProtectionStub.rejects({
status: 401,
message: '401 error message',
Expand All @@ -69,7 +69,7 @@ describe('BranchProtectionService', () => {
sinon.assert.notCalled(exportVariableStub);
});

it('should handle a 404 error (caused by branch protection not enabled)', async () => {
it('should handle a 404 error (caused by branch protection not enabled)', async function () {
getBranchProtectionStub.rejects({
status: 404,
message: 'Branch not protected',
Expand All @@ -80,7 +80,7 @@ describe('BranchProtectionService', () => {
sinon.assert.calledOnceWithExactly(exportVariableStub, 'numberOfReviewers', 0);
});

it('should handle a normal 404 error', async () => {
it('should handle a normal 404 error', async function () {
getBranchProtectionStub.rejects({
status: 404,
message: 'Regular 404 error message',
Expand All @@ -91,7 +91,7 @@ describe('BranchProtectionService', () => {
sinon.assert.notCalled(exportVariableStub);
});

it('should call warning when branch protection is enabled but receives 404 (status = 404)', async () => {
it('should call warning when branch protection is enabled but receives 404 (status = 404)', async function () {
getBranchProtectionStub.rejects({
status: 500,
message: 'Default error case',
Expand Down
46 changes: 14 additions & 32 deletions tests/CodeQLService.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import * as core from '@actions/core';
import sinon, { SinonStub } from 'sinon';
import { CodeQLService } from '../src/sasttools/CodeQLService';
import GitHub_Tools from '../src/types/GitHubTools';

describe('CodeQLService', () => {
describe('CodeQLService', function () {
let warningStub: SinonStub;
let noticeStub: SinonStub;
let infoStub: SinonStub;
Expand Down Expand Up @@ -33,7 +34,7 @@ describe('CodeQLService', () => {
sinon.restore();
});

it('should handle successful code scanning retrieval', async () => {
it('should handle successful code scanning retrieval', async function () {
iteratorStub.returns([
{
data: [
Expand Down Expand Up @@ -61,73 +62,54 @@ describe('CodeQLService', () => {
},
]);

await CodeQLService.setCodeQLFindings(octokitMock, 'owner', 'repo');
sinon.assert.callCount(exportVariableStub, 4);
await CodeQLService.setCodeQLFindings(GitHub_Tools.CODEQL, octokitMock, 'owner', 'repo');
sinon.assert.callCount(exportVariableStub, 5);
sinon.assert.calledWithExactly(exportVariableStub, 'sastTool', GitHub_Tools.CODEQL);
sinon.assert.calledWithExactly(exportVariableStub, 'SASTnumberOfSeverity1', 1);
sinon.assert.calledWithExactly(exportVariableStub, 'SASTnumberOfSeverity2', 1);
sinon.assert.calledWithExactly(exportVariableStub, 'SASTnumberOfSeverity3', 1);
sinon.assert.calledWithExactly(exportVariableStub, 'SASTnumberOfSeverity4', 1);
sinon.assert.notCalled(warningStub);
});

it('should handle a 401 error', async () => {
it('should handle a 401 error', async function () {
iteratorStub.throws({
status: 401,
message: '401 error message',
});

await CodeQLService.setCodeQLFindings(octokitMock, 'owner', 'repo');
await CodeQLService.setCodeQLFindings(GitHub_Tools.CODEQL, octokitMock, 'owner', 'repo');
sinon.assert.calledOnce(warningStub);
sinon.assert.callCount(exportVariableStub, 4);
sinon.assert.calledWithExactly(exportVariableStub, 'SASTnumberOfSeverity1', 0);
sinon.assert.calledWithExactly(exportVariableStub, 'SASTnumberOfSeverity2', 0);
sinon.assert.calledWithExactly(exportVariableStub, 'SASTnumberOfSeverity3', 0);
sinon.assert.calledWithExactly(exportVariableStub, 'SASTnumberOfSeverity4', 0);
});

it('should handle a 403 error', async () => {
it('should handle a 403 error', async function () {
iteratorStub.throws({
status: 403,
message: '403 error message',
});

await CodeQLService.setCodeQLFindings(octokitMock, 'owner', 'repo');
await CodeQLService.setCodeQLFindings(GitHub_Tools.CODEQL, octokitMock, 'owner', 'repo');
sinon.assert.calledOnce(warningStub);
sinon.assert.callCount(exportVariableStub, 4);
sinon.assert.calledWithExactly(exportVariableStub, 'SASTnumberOfSeverity1', 0);
sinon.assert.calledWithExactly(exportVariableStub, 'SASTnumberOfSeverity2', 0);
sinon.assert.calledWithExactly(exportVariableStub, 'SASTnumberOfSeverity3', 0);
sinon.assert.calledWithExactly(exportVariableStub, 'SASTnumberOfSeverity4', 0);
});

it('should handle a 404 error', async () => {
it('should handle a 404 error', async function () {
iteratorStub.throws({
status: 404,
message: '404 error message',
});

await CodeQLService.setCodeQLFindings(octokitMock, 'owner', 'repo');
await CodeQLService.setCodeQLFindings(GitHub_Tools.CODEQL, octokitMock, 'owner', 'repo');
sinon.assert.calledOnce(warningStub);
sinon.assert.callCount(exportVariableStub, 4);
sinon.assert.calledWithExactly(exportVariableStub, 'SASTnumberOfSeverity1', 0);
sinon.assert.calledWithExactly(exportVariableStub, 'SASTnumberOfSeverity2', 0);
sinon.assert.calledWithExactly(exportVariableStub, 'SASTnumberOfSeverity3', 0);
sinon.assert.calledWithExactly(exportVariableStub, 'SASTnumberOfSeverity4', 0);
});

it('should handle error other than 401, 403, 404', async () => {
it('should handle error other than 401, 403, 404', async function () {
iteratorStub.throws({
status: 500,
message: 'Default error case',
});

await CodeQLService.setCodeQLFindings(octokitMock, 'owner', 'repo');
await CodeQLService.setCodeQLFindings(GitHub_Tools.CODEQL, octokitMock, 'owner', 'repo');
sinon.assert.calledOnce(noticeStub);
sinon.assert.callCount(exportVariableStub, 4);
sinon.assert.calledWithExactly(exportVariableStub, 'SASTnumberOfSeverity1', 0);
sinon.assert.calledWithExactly(exportVariableStub, 'SASTnumberOfSeverity2', 0);
sinon.assert.calledWithExactly(exportVariableStub, 'SASTnumberOfSeverity3', 0);
sinon.assert.calledWithExactly(exportVariableStub, 'SASTnumberOfSeverity4', 0);
sinon.assert.notCalled(warningStub);
});
});
Loading
Loading