Skip to content

Commit

Permalink
feat: aseta aloituskuulutukseen tiedostot julkaisuaikana kansalaisten…
Browse files Browse the repository at this point in the history
… saataville
  • Loading branch information
haapamakim committed Mar 9, 2022
1 parent 37cb122 commit f7a50c4
Show file tree
Hide file tree
Showing 23 changed files with 558 additions and 187 deletions.
10 changes: 9 additions & 1 deletion backend/integrationtest/api/__snapshots__/api.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,15 @@ Object {
},
"kuulutusPaiva": "2022-01-02",
"siirtyySuunnitteluVaiheeseen": "2022-01-01",
"suunnitteluSopimus": undefined,
"suunnitteluSopimus": Object {
"__typename": "SuunnitteluSopimus",
"email": "Joku.Jossain@vayla.fi",
"etunimi": "Joku",
"kunta": "Nokia",
"logo": "/tiedostot/suunnitelma/1.2.246.578.5.1.2978288874.2711575506/suunnittelusopimus/logo.png",
"puhelinnumero": "123",
"sukunimi": "Jossain",
},
"velho": Object {
"__typename": "Velho",
"kunnat": Array [
Expand Down
7 changes: 2 additions & 5 deletions backend/integrationtest/api/api.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -164,14 +164,11 @@ describe("Api", () => {
// Test that fields can be removed as well
await api.tallennaProjekti({
oid,
suunnitteluSopimus: null,
muistiinpano: null,
});

const updatedProjekti2 = await loadProjektiFromDatabase(oid);
expect(updatedProjekti2.muistiinpano).to.be.equal(newNote);
expect(updatedProjekti2.aloitusKuulutus).eql(aloitusKuulutus);
expect(updatedProjekti2.suunnitteluSopimus).to.be.undefined;
expect(updatedProjekti2.kielitiedot).eql(kielitiedot);
expect(updatedProjekti2.muistiinpano).to.be.undefined;

userFixture.loginAsProjektiKayttaja(projektiPaallikko);
await api.siirraTila({
Expand Down
1 change: 1 addition & 0 deletions backend/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ const config = {

uploadBucketName: process.env.UPLOAD_BUCKET_NAME,
yllapitoBucketName: process.env.YLLAPITO_BUCKET_NAME,
publicBucketName: process.env.PUBLIC_BUCKET_NAME,
internalBucketName: process.env.INTERNAL_BUCKET_NAME,
archiveBucketName: process.env.ARCHIVE_BUCKET_NAME,

Expand Down
83 changes: 69 additions & 14 deletions backend/src/files/fileService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
} from "@aws-sdk/client-s3";
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
import { ArchivedProjektiKey } from "../database/projektiDatabase";
import { Dayjs } from "dayjs";

export type UploadFileProperties = {
fileNameWithPath: string;
Expand All @@ -26,6 +27,8 @@ export type CreateFileProperties = {
contents: Buffer;
contentType?: string;
inline?: boolean;
publicationTimestamp?: Dayjs;
copyToPublic?: boolean;
};

export type PersistFileProperties = { targetFilePathInProjekti: string; uploadedFileSource: string; oid: string };
Expand Down Expand Up @@ -55,7 +58,7 @@ export class FileService {

const fileNameFromUpload = FileService.getFileNameFromPath(filePath);
const targetPath = `/${param.targetFilePathInProjekti}/${fileNameFromUpload}`;
const targetBucketPath = FileService.getProjektiDirectory(param.oid) + targetPath;
const targetBucketPath = FileService.getYllapitoProjektiDirectory(param.oid) + targetPath;
try {
await getS3Client().send(
new CopyObjectCommand({
Expand All @@ -80,26 +83,54 @@ export class FileService {
*/
async createFileToProjekti(param: CreateFileProperties): Promise<string> {
const pathWithinProjekti = `/${param.filePathInProjekti}/${param.fileName}`;
const targetPath = FileService.getProjektiDirectory(param.oid) + pathWithinProjekti;
try {
const commandOutput = await getS3Client().send(
new PutObjectCommand({
Body: param.contents,
Bucket: config.yllapitoBucketName,
Key: targetPath,
ContentType: param.contentType,
ContentDisposition: param.inline && "inline; filename=" + param.fileName,
})
const metadata: { [key: string]: string } = {};
if (param.publicationTimestamp) {
metadata["publication-timestamp"] = param.publicationTimestamp.toISOString();
}
await FileService.putFile(
config.yllapitoBucketName,
param,
FileService.getYllapitoProjektiDirectory(param.oid) + pathWithinProjekti,
metadata
);
log.info(`Created file ${targetPath}`, commandOutput.$metadata);

if (param.copyToPublic) {
await FileService.putFile(
config.publicBucketName,
param,
FileService.getPublicProjektiDirectory(param.oid) + pathWithinProjekti,
metadata
);
}

return pathWithinProjekti;
} catch (e) {
log.error(e);
throw new Error("Error creating file to yllapito");
}
}

private static getProjektiDirectory(oid: string) {
private static async putFile(
bucket: string,
param: CreateFileProperties,
targetPath: string,
metadata: { [p: string]: string }
) {
const commandOutput = await getS3Client().send(
new PutObjectCommand({
Body: param.contents,
Bucket: bucket,
Key: targetPath,
ContentType: param.contentType,
ContentDisposition: param.inline && "inline; filename=" + param.fileName,
Metadata: metadata,
})
);
log.info(`Created file ${bucket}/${targetPath}`, commandOutput.$metadata);
}

private static getYllapitoProjektiDirectory(oid: string) {
return `yllapito/tiedostot/projekti/${oid}`;
}

Expand Down Expand Up @@ -130,7 +161,7 @@ export class FileService {
}

async archiveProjekti({ oid, timestamp }: ArchivedProjektiKey): Promise<void> {
const sourcePrefix = FileService.getProjektiDirectory(oid);
const sourcePrefix = FileService.getYllapitoProjektiDirectory(oid);
const targetPrefix = sourcePrefix + "/" + timestamp;
const sourceBucket = config.yllapitoBucketName;
const targetBucket = config.archiveBucketName;
Expand All @@ -145,6 +176,7 @@ export class FileService {
Bucket: targetBucket,
Key: targetKey,
CopySource: `${sourceBucket}/${sourceKey}`,
MetadataDirective: "REPLACE",
})
);

Expand Down Expand Up @@ -183,12 +215,35 @@ export class FileService {
}

getYllapitoPathForProjektiFile(oid: string, path: string): string | undefined {
return path ? `/${FileService.getProjektiDirectory(oid)}${path}` : undefined;
return path ? `/${FileService.getYllapitoProjektiDirectory(oid)}${path}` : undefined;
}

getPublicPathForProjektiFile(oid: string, path: string): string | undefined {
return path ? `/${FileService.getPublicProjektiDirectory(oid)}${path}` : undefined;
}

/**
* Copy file from yllapito to public bucket
*/
async publishProjektiFile(oid: string, filePathInProjekti: string, publishDate?: Dayjs): Promise<void> {
const sourceBucket = config.yllapitoBucketName;
const targetBucket = config.publicBucketName;

const s3Client = getS3Client();
const metadata: { [key: string]: string } = {};
if (publishDate) {
metadata["publication-timestamp"] = publishDate.toISOString();
}
const copyObjectParams = {
Bucket: targetBucket,
Key: `${FileService.getPublicProjektiDirectory(oid)}${filePathInProjekti}`,
CopySource: `${sourceBucket}/${FileService.getYllapitoProjektiDirectory(oid)}${filePathInProjekti}`,
MetadataDirective: "REPLACE",
Metadata: metadata,
};
const copyObjectCommandOutput = await s3Client.send(new CopyObjectCommand(copyObjectParams));
log.info("Publish file", { copyObjectParams, copyObjectCommandOutput });
}
}

export const fileService = new FileService();
11 changes: 11 additions & 0 deletions backend/src/handler/aloitusKuulutusHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { fileService } from "../files/fileService";
import { sendEmail } from "../email/email";
import { createHyvaksyttavanaEmail } from "../email/emailTemplates";
import { log } from "../logger";
import { parseDate } from "../util/dateUtil";

async function sendForApproval(projekti: DBProjekti, aloitusKuulutus: AloitusKuulutus) {
const muokkaaja = requirePermissionMuokkaa(projekti);
Expand Down Expand Up @@ -67,6 +68,8 @@ async function createAloituskuulutusPDF(
contents: Buffer.from(pdf.sisalto, "base64"),
inline: true,
contentType: "application/pdf",
publicationTimestamp: parseDate(julkaisuWaitingForApproval.kuulutusPaiva),
copyToPublic: true,
});
}

Expand Down Expand Up @@ -109,6 +112,14 @@ async function approve(projekti: DBProjekti, aloitusKuulutus: AloitusKuulutus) {
kielitiedot.toissijainenKieli,
julkaisuWaitingForApproval
);

if (projekti.suunnitteluSopimus?.logo) {
await fileService.publishProjektiFile(
projekti.oid,
projekti.suunnitteluSopimus?.logo,
parseDate(julkaisuWaitingForApproval.kuulutusPaiva)
);
}
}

await projektiDatabase.updateAloitusKuulutusJulkaisu(projekti, julkaisuWaitingForApproval);
Expand Down
Loading

0 comments on commit f7a50c4

Please sign in to comment.