Skip to content

Commit

Permalink
feat(OY2-26082): package actions multi-file download
Browse files Browse the repository at this point in the history
  • Loading branch information
pkim-gswell committed Jan 18, 2024
1 parent 6d7ad17 commit 9531480
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 59 deletions.
69 changes: 27 additions & 42 deletions src/services/api/handlers/getAttachmentUrl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@ import { STSClient, AssumeRoleCommand } from "@aws-sdk/client-sts";
import { S3Client, GetObjectCommand } from "@aws-sdk/client-s3";
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";

import * as os from "./../../../libs/opensearch-lib";
import { getStateFilter } from "../libs/auth/user";
import { opensearch } from "shared-types";
import { getPackage, getPackageChangelog } from "../libs/package";
if (!process.env.osDomain) {
throw "ERROR: osDomain env variable is required,";
}
Expand All @@ -29,52 +28,37 @@ export const handler = async (event: APIGatewayEvent) => {
try {
const body = JSON.parse(event.body);

let query: any = {};
query = {
query: {
bool: {
must: [
{
ids: {
values: [body.id],
},
},
],
},
},
};
const stateFilter = await getStateFilter(event);
if (stateFilter) {
query.query.bool.must.push(stateFilter);
}

const results = (await os.search(
process.env.osDomain,
"main",
query
)) as opensearch.Response<opensearch.main.Document>;

if (!results) {
const mainResult = await getPackage(body.id);
if (!mainResult) {
return response({
statusCode: 404,
body: { message: "No record found for the given id" },
});
}

const allAttachments = [
...(results.hits.hits[0]._source.attachments || []),
...Object.values(results.hits.hits[0]._source.rais).flatMap((entry) => [
...(entry.request?.attachments || []),
...(entry.response?.attachments || []),
...(entry.withdraw?.attachments || []),
]),
];

if (
!allAttachments.some((e) => {
return e.bucket === body.bucket && e.key === body.key;
})
) {
const stateFilter = await getStateFilter(event);
if (stateFilter) {
const stateAccessAllowed = stateFilter?.terms.state.includes(
mainResult?._source?.state?.toLocaleLowerCase() || ""
);

if (!stateAccessAllowed) {
return response({
statusCode: 404,
body: { message: "state access not permitted for the given id" },
});
}
}

// add state
// Do we want to check
const changelogs = await getPackageChangelog(body.id);
const attachmentExists = changelogs.hits.hits.some((CL) => {
return CL._source.attachments?.some(
(ATT) => ATT.bucket === body.bucket && ATT.key === body.key
);
});
if (!attachmentExists) {
return response({
statusCode: 500,
body: {
Expand Down Expand Up @@ -136,6 +120,7 @@ async function getClient(bucket: string) {
}
}

//TODO: add check for resource before signing URL
async function generatePresignedUrl(
bucket: string,
key: string,
Expand Down
4 changes: 4 additions & 0 deletions src/services/api/libs/auth/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ export const isAuthorizedToGetPackageActions = async (
);
};

// originally intended for /_search
export const getStateFilter = async (event: APIGatewayEvent) => {
// Retrieve authentication details of the user
const authDetails = getAuthDetails(event);
Expand All @@ -137,11 +138,14 @@ export const getStateFilter = async (event: APIGatewayEvent) => {
if (userAttributes["custom:state"]) {
const filter = {
terms: {
//NOTE: this could instead be
// "state.keyword": userAttributes["custom:state"],
state: userAttributes["custom:state"]
.split(",")
.map((state) => state.toLocaleLowerCase()),
},
};

return filter;
} else {
throw "State user detected, but no associated states. Cannot continue";
Expand Down
11 changes: 9 additions & 2 deletions src/services/api/libs/package/changelog.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import * as os from "../../../../libs/opensearch-lib";
import { opensearch } from "shared-types";

export const getPackageChangelog = async (packageId: string) => {
export const getPackageChangelog = async (
packageId: string,
filter: any[] = []
) => {
if (!process.env.osDomain) {
throw new Error("process.env.osDomain must be defined");
}
Expand All @@ -10,6 +13,10 @@ export const getPackageChangelog = async (packageId: string) => {
from: 0,
size: 200,
sort: [{ timestamp: "desc" }],
query: { bool: { must: [{ term: { "packageId.keyword": packageId } }] } },
query: {
bool: {
must: [{ term: { "packageId.keyword": packageId } }].concat(filter),
},
},
})) as opensearch.changelog.Response;
};
28 changes: 17 additions & 11 deletions src/services/ui/src/pages/detail/admin-changes/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { format } from "date-fns";
import { FC, useMemo } from "react";
import { opensearch } from "shared-types";
import { format } from "date-fns";
import {
Accordion,
AccordionContent,
Expand All @@ -14,21 +14,27 @@ export const AC_WithdrawEnabled: FC<opensearch.changelog.Document> = (
props
) => {
return (
<p>
{props.submitterName} has enabled package action to submit formal RAI
response
</p>
<div className="flex flex-col gap-2">
<p className="font-bold">Change made</p>
<p>
{props.submitterName} has enabled package action to submit formal RAI
response
</p>
</div>
);
};

export const AC_WithdrawDisabled: FC<opensearch.changelog.Document> = (
props
) => {
return (
<p>
{props.submitterName} has disabled package action to submit formal RAI
response
</p>
<div className="flex flex-col gap-2">
<p className="font-bold">Change made</p>
<p>
{props.submitterName} has disabled package action to submit formal RAI
response
</p>
</div>
);
};

Expand All @@ -40,9 +46,9 @@ export const AdminChange: FC<opensearch.changelog.Document> = (props) => {
const [label, Content] = useMemo(() => {
switch (props.actionType) {
case "disable-rai-withdraw":
return ["Disabled formal RAI response withdraw", AC_WithdrawDisabled];
return ["Disable formal RAI response withdraw", AC_WithdrawDisabled];
case "enable-rai-withdraw":
return ["Enabled formal RAI response withdraw", AC_WithdrawEnabled];
return ["Enable formal RAI response withdraw", AC_WithdrawEnabled];
case "update":
return ["SPA ID update", AC_Update];
default:
Expand Down
9 changes: 5 additions & 4 deletions src/services/ui/src/pages/detail/package-activity/index.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import { Accordion, DetailsSection } from "@/components";
import { FC, useMemo } from "react";
import { opensearch } from "shared-types";
import { FC, Fragment, useMemo } from "react";
import { Button } from "@/components/Inputs";
import { format } from "date-fns";
import {
Accordion,
DetailsSection,
AccordionContent,
AccordionItem,
AccordionTrigger,
} from "@/components";
import { Button } from "@/components/Inputs";
import * as Table from "@/components/Table";
import { BLANK_VALUE } from "@/consts";
import { format } from "date-fns";
import { usePackageActivities, useAttachmentService } from "./hook";

export const PA_InitialSubmission: FC<opensearch.changelog.Document> = (
Expand Down

0 comments on commit 9531480

Please sign in to comment.