Skip to content

Commit

Permalink
Merge pull request #283 from vikhyat187/grant-aws-access
Browse files Browse the repository at this point in the history
Grant aws access
  • Loading branch information
vikhyat187 authored Oct 25, 2024
2 parents 4b218f0 + 7130af6 commit 49f45f0
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 117 deletions.
24 changes: 1 addition & 23 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 1 addition & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
"@types/jest": "^29.2.5",
"@types/node": "^18.11.18",
"@types/node-fetch": "^2.6.2",
"@types/uuid": "^10.0.0",
"@typescript-eslint/eslint-plugin": "^5.47.1",
"@typescript-eslint/parser": "^5.47.1",
"eslint": "^8.31.0",
Expand All @@ -43,8 +42,7 @@
"discord-interactions": "^3.2.0",
"dotenv": "^16.0.3",
"itty-router": "^3.0.11",
"node-fetch": "^3.3.0",
"uuid": "^10.0.0"
"node-fetch": "^3.3.0"
},
"pre-commit": [
"lint-check",
Expand Down
60 changes: 24 additions & 36 deletions src/utils/awsAccess.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,26 @@
import jwt from "@tsndr/cloudflare-worker-jwt";
import { v4 as uuidv4 } from "uuid";
import { env } from "../typeDefinitions/default.types";
import config from "../../config/config";
import { discordTextResponse } from "./discordResponse";
import { DISCORD_BASE_URL, AWS_IAM_SIGNIN_URL } from "../constants/urls";

function sendDiscordMessage(content: string, channelId: number, env: env) {
return fetch(`${DISCORD_BASE_URL}/channels/${channelId}/messages`, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bot ${env.DISCORD_TOKEN}`,
},
body: JSON.stringify({
content: `${content}`,
}),
});
}

export async function processAWSAccessRequest(
discordUserId: string,
awsGroupId: string,
env: env,
TraceId: string,
channelId: number
) {
const authToken = await jwt.sign(
Expand All @@ -25,7 +36,7 @@ export async function processAWSAccessRequest(
userId: discordUserId,
};

const url = `${base_url}/aws-access/`;
const url = `${base_url}/aws-access`;

const response = await fetch(url, {
method: "POST",
Expand All @@ -37,39 +48,17 @@ export async function processAWSAccessRequest(
});

if (!response.ok) {
return fetch(`${DISCORD_BASE_URL}/channels/${channelId}/messages`, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bot ${env.DISCORD_TOKEN}`,
},
body: JSON.stringify({
content: `<@${discordUserId}> Error occurred while granting AWS access: ${response.status} ${response.statusText}`,
}),
});
const responseText = await response.text();
const errorData = JSON.parse(responseText);
const content = `<@${discordUserId}> Error occurred while granting AWS access: ${errorData.error}`;
return sendDiscordMessage(content, channelId, env);
} else {
return fetch(`${DISCORD_BASE_URL}/channels/${channelId}/messages`, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bot ${env.DISCORD_TOKEN}`,
},
body: JSON.stringify({
content: `AWS access granted successfully <@${discordUserId}>! Please head over to AWS - ${AWS_IAM_SIGNIN_URL}.`,
}),
});
const content = `AWS access granted successfully <@${discordUserId}>! Please head over to AWS - ${AWS_IAM_SIGNIN_URL}.`;
return sendDiscordMessage(content, channelId, env);
}
} catch (err) {
return fetch(`${DISCORD_BASE_URL}/channels/${channelId}/messages`, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bot ${env.DISCORD_TOKEN}`,
},
body: JSON.stringify({
content: `[TraceId: ${TraceId}] <@${discordUserId}> Error occurred while granting AWS access.`,
}),
});
const content = `<@${discordUserId}> Error occurred while granting AWS access.`;
return sendDiscordMessage(content, channelId, env);
}
}

Expand All @@ -80,15 +69,14 @@ export async function grantAWSAccess(
ctx: ExecutionContext,
channelId: number
) {
const TraceId = uuidv4();
// Immediately send a Discord response to acknowledge the command
const initialResponse = discordTextResponse(
`[TraceId: ${TraceId}] <@${discordUserId}> Processing your request to grant AWS access.`
`<@${discordUserId}> Processing your request to grant AWS access.`
);

ctx.waitUntil(
// Asynchronously call the function to grant AWS access
processAWSAccessRequest(discordUserId, awsGroupId, env, TraceId, channelId)
processAWSAccessRequest(discordUserId, awsGroupId, env, channelId)
);

// Return the immediate response within 3 seconds
Expand Down
56 changes: 1 addition & 55 deletions tests/unit/handlers/grantAwsAccessCommand.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,6 @@ import { AWS_IAM_SIGNIN_URL } from "../../../src/constants/urls";

jest.mock("node-fetch");
jest.mock("@tsndr/cloudflare-worker-jwt");
jest.mock("uuid", () => ({
v4: jest.fn(() => "123e4567-e89b-12d3-a456-426614174000"),
}));
jest.mock("../../../src/utils/discordResponse", () => ({
discordTextResponse: jest.fn(),
}));
Expand All @@ -23,7 +20,6 @@ const env = {
RDS_BASE_API_URL: "https://mock-api-url.com",
};
const channelId = 123456789;
const traceId = "123424";
const ctx = {
waitUntil: jest.fn(),
passThroughOnException: jest.fn(),
Expand Down Expand Up @@ -51,7 +47,7 @@ describe("ProcessAWSAccessRequest", () => {
channelId
);
expect(discordTextResponse).toHaveBeenCalledWith(
`[TraceId: 123e4567-e89b-12d3-a456-426614174000] <@${discordUserId}> Processing your request to grant AWS access.`
`<@${discordUserId}> Processing your request to grant AWS access.`
);

// Ensure the function returns the mocked response
Expand All @@ -75,48 +71,14 @@ describe("ProcessAWSAccessRequest", () => {
discordUserId,
awsGroupId,
env as any,
traceId,
channelId
);

console.log("Fetch calls made:", fetchCalls);

expect(fetchSpy).toHaveBeenCalledTimes(2);
expect(fetchCalls).toHaveLength(2);

expect(fetchCalls[0]).toContain("/aws-access");
expect(fetchCalls[1]).toContain("/channels/123456789/messages");
// The last call should be the error message
expect(fetchSpy).toHaveBeenNthCalledWith(
1,
expect.stringContaining("/aws-access"),
expect.objectContaining({
method: "POST",
headers: expect.objectContaining({
"Content-Type": "application/json",
Authorization: "Bearer mockJwtToken",
}),
body: JSON.stringify({
groupId: awsGroupId,
userId: discordUserId,
}),
})
);

expect(fetchSpy).toHaveBeenNthCalledWith(
2,
expect.stringContaining("/channels/123456789/messages"),
expect.objectContaining({
method: "POST",
headers: expect.objectContaining({
"Content-Type": "application/json",
Authorization: "Bot mock-discord-token",
}),
body: JSON.stringify({
content: `AWS access granted successfully <@${discordUserId}>! Please head over to AWS - ${AWS_IAM_SIGNIN_URL}.`,
}),
})
);
});

it("should handle API error", async () => {
Expand All @@ -139,30 +101,14 @@ describe("ProcessAWSAccessRequest", () => {
discordUserId,
awsGroupId,
env as any,
traceId,
channelId
);

console.log("Fetch calls made:", fetchCalls);

expect(fetchSpy).toHaveBeenCalledTimes(2);
expect(fetchCalls).toHaveLength(2);

expect(fetchCalls[0]).toContain("/aws-access");
expect(fetchCalls[1]).toContain("/channels/123456789/messages");

expect(fetchSpy).toHaveBeenLastCalledWith(
expect.stringContaining("/channels/123456789/messages"),
expect.objectContaining({
method: "POST",
headers: expect.objectContaining({
"Content-Type": "application/json",
Authorization: "Bot mock-discord-token",
}),
body: JSON.stringify({
content: `<@${discordUserId}> Error occurred while granting AWS access: 500 Internal Server Error`,
}),
})
);
});
});

0 comments on commit 49f45f0

Please sign in to comment.