Skip to content

Commit a090cb6

Browse files
[JN-1632] GCS backend for document upload (#1509)
Co-authored-by: Connor Barker <[email protected]>
1 parent 73ff0e0 commit a090cb6

File tree

26 files changed

+420
-15
lines changed

26 files changed

+420
-15
lines changed

api-admin/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ dependencies {
3838
implementation 'com.auth0:java-jwt:4.5.0'
3939
implementation 'org.liquibase:liquibase-core:4.31.0'
4040
implementation 'io.jsonwebtoken:jjwt-api:0.12.6'
41+
implementation 'com.google.guava:guava:33.4.0-jre'
4142

4243
implementation 'net.javacrumbs.shedlock:shedlock-spring:6.3.0'
4344
implementation 'net.javacrumbs.shedlock:shedlock-provider-jdbc-template:6.2.0'

api-admin/src/main/resources/application-gcp.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ env:
2020
token: ${sm://${MIXPANEL_TOKEN_SECRET_ID}}
2121
airtable:
2222
authToken: ${sm://${AIRTABLE_AUTH_TOKEN_SECRET_ID}}
23+
fileUpload:
24+
backend: GCSFileStorageBackend
2325
spring:
2426
cloud:
2527
gcp:

api-admin/src/main/resources/application.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@ env:
4848
fileUpload:
4949
backend: LocalFileStorageBackend
5050
localFileStoragePath: ${LOCAL_FILE_STORAGE_PATH:/tmp/juniper/fileupload}
51+
gcsStorageUnscannedBucketName: ${GCS_FILE_STORAGE_UNSCANNED_BUCKET_NAME:}
52+
gcsStorageCleanBucketName: ${GCS_FILE_STORAGE_CLEAN_BUCKET_NAME:}
53+
gcsStorageQuarantinedBucketName: ${GCS_FILE_STORAGE_QUARANTINED_BUCKET_NAME:}
54+
gcsFileStorageProjectId: ${GCS_FILE_STORAGE_PROJECT_ID:}
5155

5256
# Below here is non-deployment-specific
5357

api-admin/src/test/resources/application.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,15 @@ env:
1818
email:
1919
sendgridApiKey: ${SENDGRID_API_KEY:}
2020

21+
otel:
22+
sdk:
23+
disabled: true
24+
instrumentation:
25+
spring-webflux:
26+
enabled: false
27+
spring-web:
28+
enabled: false
29+
2130
# Below here is non-deployment-specific
2231

2332
# When the target is 'local' the write-config.sh script will generate this properties file. It

api-participant/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ dependencies {
3636
implementation 'com.sendgrid:sendgrid-java:4.10.3'
3737
implementation 'org.liquibase:liquibase-core:4.31.0'
3838
implementation 'com.auth0:java-jwt:4.5.0'
39+
implementation 'com.google.guava:guava:33.4.0-jre'
3940

4041
implementation 'io.jsonwebtoken:jjwt-api:0.12.6'
4142
runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.12.6',

api-participant/src/main/java/bio/terra/pearl/api/participant/service/file/ParticipantFileExtService.java

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,12 @@
33
import bio.terra.pearl.api.participant.service.AuthUtilService;
44
import bio.terra.pearl.core.model.EnvironmentName;
55
import bio.terra.pearl.core.model.file.ParticipantFile;
6+
import bio.terra.pearl.core.model.file.ScannedParticipantFileDto;
67
import bio.terra.pearl.core.model.participant.Enrollee;
78
import bio.terra.pearl.core.model.participant.ParticipantUser;
89
import bio.terra.pearl.core.service.exception.NotFoundException;
910
import bio.terra.pearl.core.service.file.ParticipantFileService;
11+
import bio.terra.pearl.core.service.file.VirusScanResult;
1012
import bio.terra.pearl.core.service.file.backends.FileStorageBackend;
1113
import bio.terra.pearl.core.service.file.backends.FileStorageBackendProvider;
1214
import java.io.IOException;
@@ -34,7 +36,7 @@ public ParticipantFileExtService(
3436
this.fileStorageBackend = fileStorageBackendProvider.get();
3537
}
3638

37-
public ParticipantFile get(
39+
public ScannedParticipantFileDto get(
3840
String portalShortcode,
3941
EnvironmentName envName,
4042
ParticipantUser participantUser,
@@ -43,9 +45,13 @@ public ParticipantFile get(
4345
authUtilService.authParticipantToPortal(participantUser.getId(), portalShortcode, envName);
4446
Enrollee enrollee =
4547
authUtilService.authParticipantUserToEnrollee(participantUser.getId(), enrolleeShortcode);
46-
return participantFileService
47-
.findByEnrolleeIdAndFileName(enrollee.getId(), fileName)
48-
.orElseThrow(() -> new NotFoundException("Could not find file"));
48+
49+
ParticipantFile file =
50+
participantFileService
51+
.findByEnrolleeIdAndFileName(enrollee.getId(), fileName)
52+
.orElseThrow(() -> new NotFoundException("Could not find file"));
53+
54+
return participantFileService.attachVirusScanResult(file);
4955
}
5056

5157
public InputStream downloadFile(
@@ -62,6 +68,13 @@ public InputStream downloadFile(
6268
.findByEnrolleeIdAndFileName(enrollee.getId(), fileName)
6369
.orElseThrow(() -> new NotFoundException("Could not find file"));
6470

71+
VirusScanResult virusScanResult =
72+
participantFileService.getVirusScanResult(participantFile.getExternalFileId());
73+
74+
if (virusScanResult == VirusScanResult.QUARANTINED) {
75+
throw new IllegalArgumentException("Virus detected in file");
76+
}
77+
6578
return fileStorageBackend.downloadFile(participantFile.getExternalFileId());
6679
}
6780

api-participant/src/main/resources/application-gcp.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ env:
1818
smartyAuthToken: ${sm://${SMARTY_AUTH_TOKEN_SECRET_ID}}
1919
mixpanel:
2020
token: ${sm://${MIXPANEL_TOKEN_SECRET_ID}}
21+
fileUpload:
22+
backend: GCSFileStorageBackend
2123
spring:
2224
cloud:
2325
gcp:

api-participant/src/main/resources/application.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ env:
3636
fileUpload:
3737
backend: LocalFileStorageBackend
3838
localFileStoragePath: ${LOCAL_FILE_STORAGE_PATH:/tmp/juniper/fileupload}
39+
gcsStorageUnscannedBucketName: ${GCS_FILE_STORAGE_UNSCANNED_BUCKET_NAME:}
40+
gcsStorageCleanBucketName: ${GCS_FILE_STORAGE_CLEAN_BUCKET_NAME:}
41+
gcsStorageQuarantinedBucketName: ${GCS_FILE_STORAGE_QUARANTINED_BUCKET_NAME:}
42+
gcsFileStorageProjectId: ${GCS_FILE_STORAGE_PROJECT_ID:}
3943
# Below here is non-deployment-specific
4044

4145
# When the target is 'local' the write-config.sh script will generate this properties file. It

api-participant/src/test/resources/application.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,15 @@ env:
1818
email:
1919
sendgridApiKey: ${SENDGRID_API_KEY:}
2020

21+
otel:
22+
sdk:
23+
disabled: true
24+
instrumentation:
25+
spring-webflux:
26+
enabled: false
27+
spring-web:
28+
enabled: false
29+
2130
# Below here is non-deployment-specific
2231

2332
# When the target is 'local' the write-config.sh script will generate this properties file. It

core/build.gradle

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ dependencies {
5050
implementation 'com.smartystreets.api:smartystreets-java-sdk:3.16.1'
5151
implementation 'org.jooq:jooq:3.20.2'
5252
implementation 'com.mixpanel:mixpanel-java:1.5.3'
53+
implementation platform('com.google.cloud:libraries-bom:26.54.0')
54+
implementation 'com.google.cloud:google-cloud-storage:2.48.1'
5355

5456
implementation 'com.google.cloud:spring-cloud-gcp-starter-secretmanager:6.0.0'
5557
implementation 'com.google.cloud:spring-cloud-gcp-starter:6.0.0'

0 commit comments

Comments
 (0)