Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions src/proxy/processors/push-action/checkAuthorEmails.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,6 @@ const exec = async (req: any, action: Action): Promise<Action> => {
const illegalEmails = uniqueAuthorEmails.filter((email) => !isEmailAllowed(email));

if (illegalEmails.length > 0) {
console.log(`The following commit author e-mails are illegal: ${illegalEmails}`);

step.error = true;
step.log(`The following commit author e-mails are illegal: ${illegalEmails}`);
step.setError(
Expand All @@ -51,7 +49,7 @@ const exec = async (req: any, action: Action): Promise<Action> => {
return action;
}

console.log(`The following commit author e-mails are legal: ${uniqueAuthorEmails}`);
step.log(`The following commit author e-mails are legal: ${uniqueAuthorEmails}`);
action.addStep(step);
return action;
};
Expand Down
41 changes: 26 additions & 15 deletions src/proxy/processors/push-action/checkCommitMessages.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
import { Action, Step } from '../../actions';
import { getCommitConfig } from '../../../config';

const isMessageAllowed = (commitMessage: string): boolean => {
const isMessageAllowed = (commitMessage: any): string | null => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we fix the any

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A comment explaining that a string response indicates failure would be good

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps also renaming the function to match output style, e.g. to checkCommitMessage

try {
const commitConfig = getCommitConfig();

// Commit message is empty, i.e. '', null or undefined
if (!commitMessage) {
console.log('No commit message included...');
return false;
// console.log('No commit message included...');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove commented lines

return 'No commit message included...';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have no idea why all the error messages end in an ellipsis, they don't need to

Suggested change
return 'No commit message included...';
return 'No commit message included';

}

// Validation for configured block pattern(s) check...
if (typeof commitMessage !== 'string') {
console.log('A non-string value has been captured for the commit message...');
return false;
// console.log('A non-string value has been captured for the commit message...');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove commented lines

return 'A non-string value has been captured for the commit message...';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return 'A non-string value has been captured for the commit message...';
return 'A non-string value has been captured for the commit message';

}

// Configured blocked literals and patterns
Expand All @@ -36,15 +36,15 @@ const isMessageAllowed = (commitMessage: string): boolean => {

// Commit message matches configured block pattern(s)
if (literalMatches.length || patternMatches.length) {
console.log('Commit message is blocked via configured literals/patterns...');
return false;
// console.log('Commit message is blocked via configured literals/patterns...');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove commented lines

return 'Commit message is blocked via configured literals/patterns...';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return 'Commit message is blocked via configured literals/patterns...';
return 'Commit message is blocked via configured literals/patterns';

}
} catch (error) {
console.log('Invalid regex pattern...');
return false;
// console.log('Invalid regex pattern...');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove commented lines

return 'Invalid regex pattern...';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return 'Invalid regex pattern...';
return 'Invalid regex pattern';

}

return true;
return null;
};

// Execute if the repo is approved
Expand All @@ -53,13 +53,23 @@ const exec = async (req: any, action: Action): Promise<Action> => {

const uniqueCommitMessages = [...new Set(action.commitData?.map((commit) => commit.message))];

const illegalMessages = uniqueCommitMessages.filter((message) => !isMessageAllowed(message));
// const illegalMessages = uniqueCommitMessages.filter((message) => !isMessageAllowed(message));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove commented line

const illegalMessages = uniqueCommitMessages.filter(
(message) => isMessageAllowed(message) !== null,
);

if (illegalMessages.length > 0) {
console.log(`The following commit messages are illegal: ${illegalMessages}`);
// console.log(`The following commit messages are illegal: ${illegalMessages}`);

step.error = true;
step.log(`The following commit messages are illegal: ${illegalMessages}`);
illegalMessages.forEach((message) => {
const error = isMessageAllowed(message);
step.log(
`Illegal commit message detected: "${message}" - Reason: ${error ?? 'Unknown reason'}`,
);
});
Comment on lines +57 to +69
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using the function twice is inefficent. Perhaps swap out filter for map, then filter the result for non-null messages


// step.error = true;
// step.log(`The following commit messages are illegal: ${illegalMessages}`);
Comment on lines +71 to +72
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can be removed

step.setError(
`\n\n\nYour push has been blocked.\nPlease ensure your commit message(s) does not contain sensitive information or URLs.\n\nThe following commit messages are illegal: ${JSON.stringify(illegalMessages)}\n\n`,
);
Expand All @@ -68,7 +78,8 @@ const exec = async (req: any, action: Action): Promise<Action> => {
return action;
}

console.log(`The following commit messages are legal: ${uniqueCommitMessages}`);
// console.log(`The following commit messages are legal: ${uniqueCommitMessages}`);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove

step.log(`The following commit messages are legal: ${JSON.stringify(uniqueCommitMessages)}`);
action.addStep(step);
return action;
};
Expand Down
6 changes: 3 additions & 3 deletions src/proxy/processors/push-action/checkEmptyBranch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@ import { Action, Step } from '../../actions';
import simpleGit from 'simple-git';
import { EMPTY_COMMIT_HASH } from '../constants';

const isEmptyBranch = async (action: Action) => {
const isEmptyBranch = async (action: Action, step: Step) => {
if (action.commitFrom === EMPTY_COMMIT_HASH) {
try {
const git = simpleGit(`${action.proxyGitPath}/${action.repoName}`);

const type = await git.raw(['cat-file', '-t', action.commitTo || '']);
return type.trim() === 'commit';
} catch (err) {
console.log(`Commit ${action.commitTo} not found: ${err}`);
step.log(`Commit ${action.commitTo} not found: ${err}`);
}
}

Expand All @@ -24,7 +24,7 @@ const exec = async (req: any, action: Action): Promise<Action> => {
return action;
}

if (await isEmptyBranch(action)) {
if (await isEmptyBranch(action, step)) {
step.setError('Push blocked: Empty branch. Please make a commit before pushing a new branch.');
action.addStep(step);
step.error = true;
Expand Down
8 changes: 4 additions & 4 deletions src/proxy/processors/push-action/checkUserPushPermission.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ const validateUser = async (userEmail: string, action: Action, step: Step): Prom
const list = await getUsers({ email: userEmail });

if (list.length > 1) {
console.error(`Multiple users found with email address ${userEmail}, ending`);
step.error = true;
step.log(`Multiple users found with email address ${userEmail}, ending`);
step.log(
`Multiple Users have email <${userEmail}> so we cannot uniquely identify the user, ending`,
);
Expand All @@ -43,15 +43,15 @@ const validateUser = async (userEmail: string, action: Action, step: Step): Prom
action.addStep(step);
return action;
} else if (list.length == 0) {
console.error(`No user with email address ${userEmail} found`);
step.log(`No user with email address ${userEmail} found`);
} else {
isUserAllowed = await isUserPushAllowed(action.url, list[0].username);
}

console.log(`User ${userEmail} permission on Repo ${action.url} : ${isUserAllowed}`);
step.log(`User ${userEmail} permission on Repo ${action.url} : ${isUserAllowed}`);

if (!isUserAllowed) {
console.log('User not allowed to Push');
step.log('User not allowed to Push');
step.error = true;
step.log(`User ${userEmail} is not allowed to push on repo ${action.url}, ending`);
step.setError(
Expand Down
2 changes: 1 addition & 1 deletion src/proxy/processors/push-action/clearBareClone.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const exec = async (req: any, action: Action): Promise<Action> => {
if (err) {
throw err;
}
console.log(`.remote is deleted!`);
step.log(`.remote is deleted!`);
});

action.addStep(step);
Expand Down
10 changes: 5 additions & 5 deletions src/proxy/processors/push-action/gitleaks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,22 +116,22 @@ const exec = async (req: any, action: Action): Promise<Action> => {
try {
config = await getPluginConfig();
} catch (e) {
console.error('failed to get gitleaks config, please fix the error:', e);
step.log(`failed to get gitleaks config, please fix the error: ${String(e)}`);
action.error = true;
step.setError('failed setup gitleaks, please contact an administrator\n');
action.addStep(step);
return action;
}

if (!config.enabled) {
console.log('gitleaks is disabled, skipping');
step.log('gitleaks is disabled, skipping');
action.addStep(step);
return action;
}

const { commitFrom, commitTo } = action;
const workingDir = `${action.proxyGitPath}/${action.repoName}`;
console.log(`Scanning range with gitleaks: ${commitFrom}:${commitTo}`, workingDir);
step.log(`Scanning range with gitleaks: ${commitFrom}:${commitTo}, ${workingDir}`);

try {
const gitRootCommit = await runCommand(workingDir, 'git', [
Expand Down Expand Up @@ -171,8 +171,8 @@ const exec = async (req: any, action: Action): Promise<Action> => {
step.setError('\n' + gitleaks.stdout + gitleaks.stderr);
}
} else {
console.log('succeeded');
console.log(gitleaks.stderr);
step.log('succeeded');
step.log(gitleaks.stderr);
}
} catch (e) {
action.error = true;
Expand Down
4 changes: 2 additions & 2 deletions test/processors/checkAuthorEmails.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
import { exec } from '../../src/proxy/processors/push-action/checkAuthorEmails';
import { Action } from '../../src/proxy/actions';
import { Action, Step } from '../../src/proxy/actions';
import * as configModule from '../../src/config';
import * as validator from 'validator';
import { CommitData } from '../../src/proxy/processors/types';
Expand Down Expand Up @@ -47,7 +47,7 @@ describe('checkAuthorEmails', () => {
});

// mock console.log to suppress output and verify calls
consoleLogSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
consoleLogSpy = vi.spyOn(Step.prototype, 'log').mockImplementation(() => {});

// setup mock action
mockAction = {
Expand Down
10 changes: 5 additions & 5 deletions test/processors/checkCommitMessages.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ describe('checkCommitMessages', () => {
const result = await exec({}, action);

expect(result.steps[0].error).toBe(true);
expect(consoleLogSpy).toHaveBeenCalledWith('No commit message included...');
expect(result.steps[0].logs.join('\n')).toContain('No commit message included...');
});

it('should block null commit messages', async () => {
Expand Down Expand Up @@ -74,7 +74,7 @@ describe('checkCommitMessages', () => {
const result = await exec({}, action);

expect(result.steps[0].error).toBe(true);
expect(consoleLogSpy).toHaveBeenCalledWith(
expect(JSON.stringify(result.steps[0])).toContain(
'A non-string value has been captured for the commit message...',
);
});
Expand Down Expand Up @@ -106,7 +106,7 @@ describe('checkCommitMessages', () => {
const result = await exec({}, action);

expect(result.steps[0].error).toBe(true);
expect(consoleLogSpy).toHaveBeenCalledWith(
expect(JSON.stringify(result.steps[0])).toContain(
'Commit message is blocked via configured literals/patterns...',
);
});
Expand Down Expand Up @@ -241,8 +241,8 @@ describe('checkCommitMessages', () => {
const result = await exec({}, action);

expect(result.steps[0].error).toBe(false);
expect(consoleLogSpy).toHaveBeenCalledWith(
expect.stringContaining('The following commit messages are legal:'),
expect(JSON.stringify(result.steps[0])).toContain(
'The following commit messages are legal:',
);
});

Expand Down
10 changes: 3 additions & 7 deletions test/processors/checkUserPushPermission.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,10 @@ import { exec } from '../../src/proxy/processors/push-action/checkUserPushPermis
describe('checkUserPushPermission', () => {
let getUsersMock: Mock;
let isUserPushAllowedMock: Mock;
let consoleLogSpy: ReturnType<typeof vi.spyOn>;
let consoleErrorSpy: ReturnType<typeof vi.spyOn>;

beforeEach(() => {
getUsersMock = vi.mocked(getUsers);
isUserPushAllowedMock = vi.mocked(isUserPushAllowed);
consoleLogSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
});

afterEach(() => {
Expand Down Expand Up @@ -62,7 +58,7 @@ describe('checkUserPushPermission', () => {
expect(stepLogSpy).toHaveBeenLastCalledWith(
'User db-user@test.com is allowed to push on repo https://github.com/finos/git-proxy.git',
);
expect(consoleLogSpy).toHaveBeenLastCalledWith(
expect(stepLogSpy).toHaveBeenCalledWith(
'User db-user@test.com permission on Repo https://github.com/finos/git-proxy.git : true',
);
});
Expand All @@ -81,7 +77,7 @@ describe('checkUserPushPermission', () => {
`Your push has been blocked (db-user@test.com is not allowed to push on repo https://github.com/finos/git-proxy.git)`,
);
expect(result.steps[0].errorMessage).toContain('Your push has been blocked');
expect(consoleLogSpy).toHaveBeenLastCalledWith('User not allowed to Push');
expect(stepLogSpy).toHaveBeenCalledWith('User not allowed to Push');
});

it('should reject push when no user found for git account', async () => {
Expand Down Expand Up @@ -110,7 +106,7 @@ describe('checkUserPushPermission', () => {
expect(stepLogSpy).toHaveBeenLastCalledWith(
'Your push has been blocked (there are multiple users with email db-user@test.com)',
);
expect(consoleErrorSpy).toHaveBeenLastCalledWith(
expect(stepLogSpy).toHaveBeenCalledWith(
'Multiple users found with email address db-user@test.com, ending',
);
});
Expand Down
13 changes: 7 additions & 6 deletions test/processors/gitLeaks.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ describe('gitleaks', () => {
let getAPIs: any;
let fsModule: any;
let spawn: any;
const stepLogSpy = vi.spyOn(Step.prototype, 'log');

beforeEach(async () => {
vi.clearAllMocks();
Expand Down Expand Up @@ -89,9 +90,8 @@ describe('gitleaks', () => {
expect(stepSpy).toHaveBeenCalledWith(
'failed setup gitleaks, please contact an administrator\n',
);
expect(errorStub).toHaveBeenCalledWith(
'failed to get gitleaks config, please fix the error:',
expect.any(Error),
expect(stepLogSpy).toHaveBeenCalledWith(
expect.stringContaining('failed to get gitleaks config, please fix the error:'),
);
});

Expand All @@ -103,7 +103,7 @@ describe('gitleaks', () => {
expect(result.error).toBe(false);
expect(result.steps).toHaveLength(1);
expect(result.steps[0].error).toBe(false);
expect(logStub).toHaveBeenCalledWith('gitleaks is disabled, skipping');
expect(JSON.stringify(result.steps[0])).toContain('gitleaks is disabled, skipping');
});

it('should handle successful scan with no findings', async () => {
Expand Down Expand Up @@ -140,12 +140,13 @@ describe('gitleaks', () => {
} as any);

const result = await exec(req, action);
const stepRes = JSON.stringify(result.steps[0]);

expect(result.error).toBe(false);
expect(result.steps).toHaveLength(1);
expect(result.steps[0].error).toBe(false);
expect(logStub).toHaveBeenCalledWith('succeeded');
expect(logStub).toHaveBeenCalledWith('No leaks found');
expect(stepRes).toContain('succeeded');
expect(stepRes).toContain('No leaks found');
});

it('should handle scan with findings', async () => {
Expand Down
Loading