Skip to content

Commit

Permalink
minor changes
Browse files Browse the repository at this point in the history
  • Loading branch information
Harminder84 committed Aug 21, 2023
1 parent e82fb64 commit a4aad3f
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 23 deletions.
12 changes: 3 additions & 9 deletions src/github/installation.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ describe("InstallationWebhookHandler", () => {
});
});
describe.each(
["created", "new_permissions_accepted"]
["new_permissions_accepted"]
)("should set security permissions accepted field in subscriptions", (action) => {
it(`${action} action`, async () => {
await installationWebhookHandler(getWebhookContext({ cloud: true, action }), jiraClient, util, GITHUB_INSTALLATION_ID);
Expand Down Expand Up @@ -121,12 +121,6 @@ describe("InstallationWebhookHandler", () => {

});

it("should not submit workspace to link for created action", async () => {
const webhookContext = getWebhookContext({ cloud: true, action: "created" });
await installationWebhookHandler(webhookContext, jiraClient, util, GITHUB_INSTALLATION_ID);
expect(submitSecurityWorkspaceToLink).toBeCalledTimes(0);

});
it("should throw error if subscription is not found", async () => {
const webhookContext = getWebhookContext({ cloud: true });
await expect(installationWebhookHandler(webhookContext, jiraClient, util, 0)).rejects.toThrow("Subscription not found");
Expand Down Expand Up @@ -168,7 +162,7 @@ describe("InstallationWebhookHandler", () => {

});
describe.each(
["created", "new_permissions_accepted"]
["new_permissions_accepted"]
)("should not set security permissions accepted field in subscriptions when FF is disabled", (action) => {
it(`${action} action`, async () => {
when(booleanFlag).calledWith(BooleanFlags.ENABLE_GITHUB_SECURITY_IN_JIRA, expect.anything()).mockResolvedValue(false);
Expand All @@ -180,7 +174,7 @@ describe("InstallationWebhookHandler", () => {
});

describe.each(
["created", "new_permissions_accepted"]
["new_permissions_accepted"]
)("should set security permissions accepted field in subscriptions", (action) => {
it(`${action} action`, async () => {
await installationWebhookHandler(getWebhookContext({ cloud: false, action }), jiraClient, util, GITHUB_INSTALLATION_ID);
Expand Down
13 changes: 5 additions & 8 deletions src/github/installation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import { emitWebhookProcessedMetrics } from "../util/webhook-utils";
import Logger from "bunyan";
import { findOrStartSync } from "../sync/sync-utils";

const SECURITY_PERMISSIONS = ["secret_scanning_alerts", "security_events", "vulnerability_alerts"];
const SECURITY_EVENTS = ["secret_scanning_alert", "code_scanning_alert", "dependabot_alert"];
export const SECURITY_PERMISSIONS = ["secret_scanning_alerts", "security_events", "vulnerability_alerts"];
export const SECURITY_EVENTS = ["secret_scanning_alert", "code_scanning_alert", "dependabot_alert"];

export const installationWebhookHandler = async (
context: WebhookContext<InstallationEvent>,
Expand Down Expand Up @@ -51,17 +51,14 @@ export const installationWebhookHandler = async (
let jiraResponse;

try {
if (action === "created" && hasSecurityPermissionsAndEvents(permissions, events)) {
return await setSecurityPermissionAccepted(subscription, logger);

} else if (action === "new_permissions_accepted" && hasSecurityPermissionsAndEvents(permissions, events) && !subscription.isSecurityPermissionsAccepted) {
if (action === "new_permissions_accepted" && hasSecurityPermissionsAndEvents(permissions, events) && !subscription.isSecurityPermissionsAccepted) {
jiraResponse = await submitSecurityWorkspaceToLink(installation, subscription, logger);
logger.info({ subscriptionId: subscription.id }, "Linked security workspace via backfill");

await setSecurityPermissionAccepted(subscription, logger);

await findOrStartSync(subscription, logger, "full", subscription.backfillSince, ["dependabotAlert", "secretScanningAlert"], { source: "webhook-security-permissions-accepted" });
logger.info({ subscriptionId: subscription.id }, "Triggered security backfill successfully");

await setSecurityPermissionAccepted(subscription, logger);
}

const webhookReceived = context.webhookReceived;
Expand Down
4 changes: 2 additions & 2 deletions src/routes/github/webhook/webhook-receiver-post.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,7 @@ describe("webhook-receiver-post", () => {
}));
});
describe.each(
["created", "new_permissions_accepted"]
["new_permissions_accepted"]
)("should call installation handler", (action) => {
it(`${action} action`, async() => {
req = createGHESReqForEvent("installation", action, EXIST_GHES_UUID, { installation: { id: 123 } } as unknown as InstallationEvent);
Expand All @@ -354,7 +354,7 @@ describe("webhook-receiver-post", () => {

});

it("should not call installation handler for other than created/new_permissions_accepted action", async () => {
it("should not call installation handler for other than new_permissions_accepted action", async () => {
req = createGHESReqForEvent("installation", "suspend", EXIST_GHES_UUID, { installation: { id: 123 } } as unknown as InstallationEvent);
const spy = jest.fn();
jest.mocked(GithubWebhookMiddleware).mockImplementation(() => spy);
Expand Down
2 changes: 1 addition & 1 deletion src/routes/github/webhook/webhook-receiver-post.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ const webhookRouter = async (context: WebhookContext) => {
await GithubWebhookMiddleware(secretScanningAlertWebhookHandler)(context);
break;
case "installation":
if (context.action === "created" || context.action === "new_permissions_accepted") {
if (context.action === "new_permissions_accepted") {
await GithubWebhookMiddleware(installationWebhookHandler)(context);
}
break;
Expand Down
35 changes: 32 additions & 3 deletions src/services/subscription-installation-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { GitHubServerApp } from "models/github-server-app";
import { getCloudOrServerFromGitHubAppId } from "utils/get-cloud-or-server";
import { BooleanFlags, booleanFlag } from "~/src/config/feature-flags";
import { JiraClient } from "~/src/models/jira-client";
import { SECURITY_EVENTS, SECURITY_PERMISSIONS } from "../github/installation";

export const hasAdminAccess = async (githubToken: string, jiraHost: string, gitHubInstallationId: number, logger: Logger, gitHubServerAppIdPk?: number): Promise<boolean> => {
const metrics = {
Expand Down Expand Up @@ -108,8 +109,14 @@ export const verifyAdminPermsAndFinishInstallation =

if (await booleanFlag(BooleanFlags.ENABLE_GITHUB_SECURITY_IN_JIRA, installation.jiraHost)) {
try {
await submitSecurityWorkspaceToLink(installation, subscription, log);
log.info({ subscriptionId: subscription.id }, "Linked security workspace");
if (subscription.isSecurityPermissionsAccepted) {
await submitSecurityWorkspaceToLink(installation, subscription, log);
} else if (await hasSecurityPermissionsAndEvents(installation, gitHubServerAppIdPk, log, metrics)) {
await Promise.allSettled([
await setSecurityPermissionAccepted(subscription, log),
await submitSecurityWorkspaceToLink(installation, subscription, log)
]);
}
} catch (err) {
log.warn({ err }, "Failed to submit security workspace to Jira");
}
Expand Down Expand Up @@ -160,5 +167,27 @@ export const submitSecurityWorkspaceToLink = async (
logger: Logger
) => {
const jiraClient = await JiraClient.getNewClient(installation, logger);
return await jiraClient.linkedWorkspace(subscription.id);
await jiraClient.linkedWorkspace(subscription.id);
logger.info({ subscriptionId: subscription.id }, "Linked security workspace");
};

const hasSecurityPermissionsAndEvents = async (installation: Installation, gitHubServerAppId: number | undefined, logger: Logger, metrics: any) => {
try {
const gitHubAppClient = await createAppClient(logger, installation.jiraHost, gitHubServerAppId, metrics);
const { data: ghApp } = await gitHubAppClient.getApp();
return SECURITY_PERMISSIONS.every(securityPermission => securityPermission in ghApp.permissions) &&
SECURITY_EVENTS.every((securityEvent) => ghApp.events.includes(securityEvent));
} catch (err) {
logger.warn({ err }, "Failed to fetch GitHub app details for evaluating security permissions and events");
throw err;
}
};

const setSecurityPermissionAccepted = async (subscription: Subscription, logger: Logger) => {
try {
await subscription.update({ isSecurityPermissionsAccepted: true });
} catch (err) {
logger.warn({ err }, "Failed to set security permissions accepted field in Subscriptions");
throw err;
}
};

0 comments on commit a4aad3f

Please sign in to comment.