diff --git a/bySaS/index.test.ts b/bySaS/index.test.ts index 1010219..dfaa9f7 100644 --- a/bySaS/index.test.ts +++ b/bySaS/index.test.ts @@ -2,6 +2,7 @@ import func from "./index"; import { Context, HttpRequest } from "@azure/functions"; import { Substitute } from "@fluffy-spoon/substitute"; import { env } from "process"; +import { decode } from "querystring"; // Manually load up env variables, as the func runtime would //require("dotenv-safe").config(); describe("Unit test bySas", () => { @@ -35,8 +36,16 @@ describe("Unit test bySas", () => { }); }); - describe("Ideal case", () => { - it("Basic", async () => { + /** + * Azurite must be running ! + */ + describe.each([ + ["None", undefined], + ["SAS_LIMIT_HOURS", 6], + ])("Adding '%s' to env", (varName, value) => { + it("Full test", async () => { + env[varName] = String(value); + const DEFAULT_SAS_LIMIT = 24; const [context, request] = formatUploadRequest("test", null, { "x-forwarded-for": "1.1.1.1", }); @@ -44,7 +53,16 @@ describe("Unit test bySas", () => { expect(response.status).toBe(200); console.log(response.body); expect(response.body).toBeDefined(); - }, 10000); + const qs = decode(response.body.split("?")[1]); + // Checking sas validity span. When not provided this value should be 24h + const sasValidFrom = new Date(qs.st as string); + const sasValidTo = new Date(qs.se as string); + const timeDiff = sasValidTo.getTime() - sasValidFrom.getTime(); + expect(Math.round(timeDiff / 1000 / 3600)).toBe( + value ?? DEFAULT_SAS_LIMIT + ); + //expect(response.body) + }, 15000); }); }); diff --git a/bySaS/index.ts b/bySaS/index.ts index 32eba59..e5708e7 100644 --- a/bySaS/index.ts +++ b/bySaS/index.ts @@ -13,7 +13,9 @@ import { } from "@azure/storage-blob"; import { v4 as uuidv4 } from "uuid"; import HTTP_CODES from "http-status-enum"; -import { formatReply } from "../common/index"; +import { formatReply, getEnvVar } from "../common/index"; + +const DEFAULT_HOURS_LIMIT = 24; export default async function httpTrigger( context: Context, @@ -48,8 +50,20 @@ export default async function httpTrigger( }); return formatReply(`Unexpected error.`, HTTP_CODES.INTERNAL_SERVER_ERROR); } + + const hoursLimit = getEnvVar( + "SAS_LIMIT_HOURS", + DEFAULT_HOURS_LIMIT, + context + ); + // @TODO: A "file count by ip" limit could be implemented - const sasKey = await generateSasKeyForClient(blobClient, inboundIp); + const sasKey = await generateSasKeyForClient( + blobClient, + inboundIp, + hoursLimit + ); + context.log.info( `Successfully generated SAS key for file ${filename} and ip ${inboundIp}` ); diff --git a/common/index.ts b/common/index.ts index b352cf6..4f4a0ea 100644 --- a/common/index.ts +++ b/common/index.ts @@ -1,3 +1,6 @@ +import { env } from "process"; +import type { Context } from "@azure/functions"; + /** * Use a message * @param message @@ -16,3 +19,19 @@ export function formatReply( res.headers = headers; return res; } + +/** + * Safely retrieve a var from the environment. + * @param varName Name of the env variable + * @param fallback Fallback value + * @param ctx used to issue a warning when a variable isn't defined + * @returns the var value of a fallback + */ +export function getEnvVar(varName: string, fallback: T, ctx: Context): T { + const envVar = env[varName]; + if (envVar === undefined) { + ctx.log.warn(`${varName} isn't defined ! Defaulting to ${fallback}.`); + return fallback; + } + return envVar as unknown as T; +}