Skip to content

Commit 357d0ef

Browse files
committed
caching
1 parent 4e9780b commit 357d0ef

File tree

3 files changed

+66
-12
lines changed

3 files changed

+66
-12
lines changed

src/api/functions/redisCache.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { type Redis } from "ioredis";
2+
3+
export async function getRedisKey<T>({
4+
redisClient,
5+
key,
6+
parseJson = false,
7+
}: {
8+
redisClient: Redis;
9+
key: string;
10+
parseJson?: boolean;
11+
}) {
12+
const resp = await redisClient.get(key);
13+
if (!resp) {
14+
return null;
15+
}
16+
return parseJson ? (JSON.parse(resp) as T) : (resp as string);
17+
}
18+
19+
export async function setRedisKey({
20+
redisClient,
21+
key,
22+
value,
23+
expiresSec,
24+
}: {
25+
redisClient: Redis;
26+
key: string;
27+
value: string;
28+
expiresSec?: number;
29+
}) {
30+
if (expiresSec) {
31+
return await redisClient.set(key, value, "EX", expiresSec);
32+
}
33+
return await redisClient.set(key, value);
34+
}

src/api/routes/iam.ts

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,17 @@ import {
1919
NotFoundError,
2020
} from "../../common/errors/index.js";
2121
import { DynamoDBClient, PutItemCommand } from "@aws-sdk/client-dynamodb";
22-
import { genericConfig, roleArns } from "../../common/config.js";
22+
import {
23+
GENERIC_CACHE_SECONDS,
24+
genericConfig,
25+
roleArns,
26+
} from "../../common/config.js";
2327
import { marshall } from "@aws-sdk/util-dynamodb";
2428
import {
2529
invitePostRequestSchema,
2630
groupMappingCreatePostSchema,
27-
entraActionResponseSchema,
2831
groupModificationPatchSchema,
2932
EntraGroupActions,
30-
entraGroupMembershipListResponse,
3133
entraProfilePatchRequest,
3234
} from "../../common/types/iam.js";
3335
import {
@@ -45,6 +47,7 @@ import { AvailableSQSFunctions, SQSPayload } from "common/types/sqsMessage.js";
4547
import { SendMessageBatchCommand, SQSClient } from "@aws-sdk/client-sqs";
4648
import { v4 as uuidv4 } from "uuid";
4749
import { randomUUID } from "crypto";
50+
import { getRedisKey, setRedisKey } from "api/functions/redisCache.js";
4851

4952
const iamRoutes: FastifyPluginAsync = async (fastify, _options) => {
5053
const getAuthorizedClients = async () => {
@@ -572,21 +575,36 @@ No action is required from you at this time.
572575
),
573576
onRequest: fastify.authorizeFromSchema,
574577
},
575-
async (_request, reply) => {
578+
async (request, reply) => {
576579
const entraIdToken = await getEntraIdToken(
577580
await getAuthorizedClients(),
578581
fastify.environmentConfig.AadValidClientId,
579582
undefined,
580583
genericConfig.EntraSecretName,
581584
);
582-
return reply
583-
.status(200)
584-
.send(
585-
await getServicePrincipalOwnedGroups(
586-
entraIdToken,
587-
fastify.environmentConfig.EntraServicePrincipalId,
588-
),
589-
);
585+
const { redisClient } = fastify;
586+
const key = `entra_manageable_groups_${fastify.environmentConfig.EntraServicePrincipalId}`;
587+
const redisResponse = await getRedisKey<
588+
{ displayName: string; id: string }[]
589+
>({ redisClient, key, parseJson: true });
590+
if (redisResponse) {
591+
request.log.debug("Got manageable groups from Redis cache.");
592+
return reply.status(200).send(redisResponse);
593+
}
594+
const freshData = await getServicePrincipalOwnedGroups(
595+
entraIdToken,
596+
fastify.environmentConfig.EntraServicePrincipalId,
597+
);
598+
request.log.debug(
599+
"Got manageable groups from Entra ID, setting to cache.",
600+
);
601+
await setRedisKey({
602+
redisClient,
603+
key,
604+
value: JSON.stringify(freshData),
605+
expiresSec: GENERIC_CACHE_SECONDS,
606+
});
607+
return reply.status(200).send(freshData);
590608
},
591609
);
592610
};

src/common/config.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ type ValueOrArray<T> = T | ArrayOfValueOrArray<T>;
88

99
type AzureRoleMapping = Record<string, readonly AppRoles[]>;
1010

11+
export const GENERIC_CACHE_SECONDS = 120;
12+
1113
export type ConfigType = {
1214
UserFacingUrl: string;
1315
AzureRoleMapping: AzureRoleMapping;

0 commit comments

Comments
 (0)