• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

DataBiosphere / consent / #5046

25 Apr 2024 01:37PM UTC coverage: 76.036% (-0.1%) from 76.14%
#5046

push

web-flow
[DUOS-2660][DCJ-90][risk=no] Service Test MockitoExtension Refactor (#2142)

9557 of 12569 relevant lines covered (76.04%)

0.76 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

82.43
/src/main/java/org/broadinstitute/consent/http/resources/DataAccessRequestResourceVersion2.java
1
package org.broadinstitute.consent.http.resources;
2

3
import com.google.cloud.storage.BlobId;
4
import com.google.common.base.Strings;
5
import com.google.inject.Inject;
6
import io.dropwizard.auth.Auth;
7
import jakarta.annotation.security.PermitAll;
8
import jakarta.annotation.security.RolesAllowed;
9
import jakarta.ws.rs.BadRequestException;
10
import jakarta.ws.rs.Consumes;
11
import jakarta.ws.rs.DELETE;
12
import jakarta.ws.rs.ForbiddenException;
13
import jakarta.ws.rs.GET;
14
import jakarta.ws.rs.NotFoundException;
15
import jakarta.ws.rs.POST;
16
import jakarta.ws.rs.PUT;
17
import jakarta.ws.rs.Path;
18
import jakarta.ws.rs.PathParam;
19
import jakarta.ws.rs.Produces;
20
import jakarta.ws.rs.core.Context;
21
import jakarta.ws.rs.core.MediaType;
22
import jakarta.ws.rs.core.Response;
23
import jakarta.ws.rs.core.StreamingOutput;
24
import jakarta.ws.rs.core.UriInfo;
25
import java.io.IOException;
26
import java.io.InputStream;
27
import java.net.URI;
28
import java.util.Collections;
29
import java.util.List;
30
import java.util.Objects;
31
import java.util.UUID;
32
import java.util.stream.Collectors;
33
import java.util.stream.Stream;
34
import org.apache.commons.lang3.StringUtils;
35
import org.broadinstitute.consent.http.cloudstore.GCSService;
36
import org.broadinstitute.consent.http.enumeration.DarDocumentType;
37
import org.broadinstitute.consent.http.enumeration.UserRoles;
38
import org.broadinstitute.consent.http.models.AuthUser;
39
import org.broadinstitute.consent.http.models.DataAccessRequest;
40
import org.broadinstitute.consent.http.models.DataAccessRequestData;
41
import org.broadinstitute.consent.http.models.DataUse;
42
import org.broadinstitute.consent.http.models.Dataset;
43
import org.broadinstitute.consent.http.models.Error;
44
import org.broadinstitute.consent.http.models.User;
45
import org.broadinstitute.consent.http.service.DataAccessRequestService;
46
import org.broadinstitute.consent.http.service.DatasetService;
47
import org.broadinstitute.consent.http.service.EmailService;
48
import org.broadinstitute.consent.http.service.MatchService;
49
import org.broadinstitute.consent.http.service.UserService;
50
import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
51
import org.glassfish.jersey.media.multipart.FormDataParam;
52

53
@Path("api/dar/v2")
54
public class DataAccessRequestResourceVersion2 extends Resource {
55

56
  private final DataAccessRequestService dataAccessRequestService;
57
  private final EmailService emailService;
58
  private final GCSService gcsService;
59
  private final MatchService matchService;
60
  private final UserService userService;
61
  private final DatasetService datasetService;
62

63
  @Inject
64
  public DataAccessRequestResourceVersion2(
65
      DataAccessRequestService dataAccessRequestService,
66
      EmailService emailService,
67
      GCSService gcsService,
68
      UserService userService,
69
      DatasetService datasetService,
70
      MatchService matchService
71
  ) {
1✔
72
    this.dataAccessRequestService = dataAccessRequestService;
1✔
73
    this.emailService = emailService;
1✔
74
    this.gcsService = gcsService;
1✔
75
    this.userService = userService;
1✔
76
    this.datasetService = datasetService;
1✔
77
    this.matchService = matchService;
1✔
78
  }
1✔
79

80
  @GET
81
  @Produces("application/json")
82
  @PermitAll
83
  public Response getDataAccessRequests(@Auth AuthUser authUser) {
84
    try {
85
      User user = userService.findUserByEmail(authUser.getEmail());
1✔
86
      List<DataAccessRequest> dars = dataAccessRequestService.getDataAccessRequestsByUserRole(user);
1✔
87
      return Response.ok().entity(dars).build();
1✔
88
    } catch (Exception e) {
×
89
      return createExceptionResponse(e);
×
90
    }
91
  }
92

93
  @POST
94
  @Consumes("application/json")
95
  @Produces("application/json")
96
  @RolesAllowed(RESEARCHER)
97
  public Response createDataAccessRequest(
98
      @Auth AuthUser authUser, @Context UriInfo info, String dar) {
99
    try {
100
      User user = findUserByEmail(authUser.getEmail());
1✔
101
      if (Objects.isNull(user.getLibraryCards()) || user.getLibraryCards().isEmpty()) {
1✔
102
        throw new IllegalArgumentException("User must have a library card to create a DAR.");
1✔
103
      }
104

105
      DataAccessRequest payload = populateDarFromJsonString(user, dar);
1✔
106
      DataAccessRequest newDar = dataAccessRequestService.createDataAccessRequest(user, payload);
1✔
107
      Integer collectionId = newDar.getCollectionId();
1✔
108
      try {
109
        emailService.sendNewDARCollectionMessage(collectionId);
1✔
110
      } catch (Exception e) {
×
111
        // non-fatal exception
112
        logException("Exception sending email for collection id: " + collectionId, e);
×
113
      }
1✔
114
      URI uri = info.getRequestUriBuilder().build();
1✔
115
      matchService.reprocessMatchesForPurpose(newDar.getReferenceId());
1✔
116
      return Response.created(uri).entity(newDar.convertToSimplifiedDar()).build();
1✔
117
    } catch (Exception e) {
1✔
118
      return createExceptionResponse(e);
1✔
119
    }
120
  }
121

122
  @GET
123
  @Path("/{referenceId}")
124
  @Produces("application/json")
125
  @PermitAll
126
  public Response getByReferenceId(
127
      @Auth AuthUser authUser, @PathParam("referenceId") String referenceId) {
128
    validateAuthedRoleUser(
1✔
129
        Stream.of(UserRoles.ADMIN, UserRoles.CHAIRPERSON, UserRoles.MEMBER)
1✔
130
            .collect(Collectors.toList()),
1✔
131
        authUser, referenceId);
132
    try {
133
      DataAccessRequest dar = dataAccessRequestService.findByReferenceId(referenceId);
1✔
134
      if (Objects.nonNull(dar)) {
1✔
135
        return Response.status(Response.Status.OK).entity(dar.convertToSimplifiedDar()).build();
1✔
136
      }
137
      return Response.status(Response.Status.NOT_FOUND)
×
138
          .entity(
×
139
              new Error(
140
                  "Unable to find Data Access Request with reference id: " + referenceId,
141
                  Response.Status.NOT_FOUND.getStatusCode()))
×
142
          .build();
×
143
    } catch (Exception e) {
×
144
      return createExceptionResponse(e);
×
145
    }
146
  }
147

148
  @PUT
149
  @Path("/{referenceId}")
150
  @Produces("application/json")
151
  @RolesAllowed(RESEARCHER)
152
  public Response updateByReferenceId(
153
      @Auth AuthUser authUser, @PathParam("referenceId") String referenceId, String dar) {
154
    try {
155
      User user = findUserByEmail(authUser.getEmail());
1✔
156
      DataAccessRequest originalDar = dataAccessRequestService.findByReferenceId(referenceId);
1✔
157
      checkAuthorizedUpdateUser(user, originalDar);
1✔
158
      DataAccessRequestData data = DataAccessRequestData.fromString(dar);
1✔
159
      // Keep dar data reference id in sync with the dar until we fully deprecate
160
      // it in dar data.
161
      data.setReferenceId(originalDar.getReferenceId());
1✔
162
      originalDar.setData(data);
1✔
163
      DataAccessRequest updatedDar =
1✔
164
          dataAccessRequestService.updateByReferenceId(user, originalDar);
1✔
165
      matchService.reprocessMatchesForPurpose(referenceId);
1✔
166
      return Response.ok().entity(updatedDar.convertToSimplifiedDar()).build();
1✔
167
    } catch (Exception e) {
1✔
168
      return createExceptionResponse(e);
1✔
169
    }
170
  }
171

172
  @GET
173
  @Produces("application/json")
174
  @Path("/draft")
175
  @RolesAllowed(RESEARCHER)
176
  public Response getDraftDataAccessRequests(@Auth AuthUser authUser) {
177
    try {
178
      User user = findUserByEmail(authUser.getEmail());
1✔
179
      List<DataAccessRequest> draftDars = dataAccessRequestService.findAllDraftDataAccessRequestsByUser(
1✔
180
          user.getUserId());
1✔
181
      return Response.ok().entity(draftDars).build();
1✔
182
    } catch (Exception e) {
1✔
183
      return createExceptionResponse(e);
1✔
184
    }
185
  }
186

187
  @GET
188
  @Produces("application/json")
189
  @Path("/draft/{referenceId}")
190
  @RolesAllowed(RESEARCHER)
191
  public Response getDraftDar(@Auth AuthUser authUser, @PathParam("referenceId") String id) {
192
    try {
193
      User user = findUserByEmail(authUser.getEmail());
1✔
194
      DataAccessRequest dar = dataAccessRequestService.findByReferenceId(id);
1✔
195
      if (dar.getUserId().equals(user.getUserId())) {
1✔
196
        return Response.ok().entity(dar).build();
1✔
197
      }
198
      throw new ForbiddenException("User does not have permission");
1✔
199
    } catch (Exception e) {
1✔
200
      return createExceptionResponse(e);
1✔
201
    }
202
  }
203

204
  @POST
205
  @Consumes("application/json")
206
  @Produces("application/json")
207
  @Path("/draft")
208
  @RolesAllowed(RESEARCHER)
209
  public Response createDraftDataAccessRequest(
210
      @Auth AuthUser authUser, @Context UriInfo info, String dar) {
211
    try {
212
      User user = findUserByEmail(authUser.getEmail());
1✔
213
      DataAccessRequest newDar = populateDarFromJsonString(user, dar);
1✔
214
      DataAccessRequest result =
1✔
215
          dataAccessRequestService.insertDraftDataAccessRequest(user, newDar);
1✔
216
      URI uri = info.getRequestUriBuilder().path("/" + result.getReferenceId()).build();
1✔
217
      return Response.created(uri).entity(result.convertToSimplifiedDar()).build();
1✔
218
    } catch (Exception e) {
×
219
      return createExceptionResponse(e);
×
220
    }
221
  }
222

223
  @PUT
224
  @Consumes("application/json")
225
  @Produces("application/json")
226
  @Path("/draft/{referenceId}")
227
  @RolesAllowed(RESEARCHER)
228
  public Response updatePartialDataAccessRequest(
229
      @Auth AuthUser authUser, @PathParam("referenceId") String referenceId, String dar) {
230
    try {
231
      User user = findUserByEmail(authUser.getEmail());
1✔
232
      DataAccessRequest originalDar = dataAccessRequestService.findByReferenceId(referenceId);
1✔
233
      checkAuthorizedUpdateUser(user, originalDar);
1✔
234
      DataAccessRequestData data = DataAccessRequestData.fromString(dar);
1✔
235
      // Keep dar data reference id in sync with the dar until we fully deprecate
236
      // it in dar data.
237
      data.setReferenceId(originalDar.getReferenceId());
1✔
238
      originalDar.setData(data);
1✔
239
      originalDar.setDatasetIds(data.getDatasetIds());
1✔
240
      DataAccessRequest updatedDar =
1✔
241
          dataAccessRequestService.updateByReferenceId(user, originalDar);
1✔
242
      return Response.ok().entity(updatedDar.convertToSimplifiedDar()).build();
1✔
243
    } catch (Exception e) {
1✔
244
      return createExceptionResponse(e);
1✔
245
    }
246
  }
247

248
  @GET
249
  @Produces({MediaType.APPLICATION_OCTET_STREAM, MediaType.APPLICATION_JSON})
250
  @Path("/{referenceId}/irbDocument")
251
  @RolesAllowed({ADMIN, CHAIRPERSON, MEMBER, RESEARCHER})
252
  public Response getIrbDocument(
253
      @Auth AuthUser authUser,
254
      @PathParam("referenceId") String referenceId) {
255
    try {
256
      DataAccessRequest dar = getDarById(referenceId);
1✔
257
      validateAuthedRoleUser(
1✔
258
          Stream.of(UserRoles.ADMIN, UserRoles.CHAIRPERSON, UserRoles.MEMBER)
1✔
259
              .collect(Collectors.toList()),
1✔
260
          authUser, referenceId);
261
      if (dar.getData() != null &&
1✔
262
          StringUtils.isNotEmpty(dar.getData().getIrbDocumentLocation()) &&
1✔
263
          StringUtils.isNotEmpty(dar.getData().getIrbDocumentName())
1✔
264
      ) {
265
        String blobIdName = dar.getData().getIrbDocumentLocation();
1✔
266
        String fileName = dar.getData().getIrbDocumentName();
1✔
267
        InputStream is = gcsService.getDocument(blobIdName);
1✔
268
        StreamingOutput stream = createStreamingOutput(is);
1✔
269
        return Response.ok(stream)
1✔
270
            .header("Content-Disposition", "attachment; filename=" + fileName)
1✔
271
            .build();
1✔
272
      }
273
      throw new NotFoundException();
1✔
274
    } catch (Exception e) {
1✔
275
      return createExceptionResponse(e);
1✔
276
    }
277
  }
278

279
  @POST
280
  @Consumes(MediaType.MULTIPART_FORM_DATA)
281
  @Produces(MediaType.APPLICATION_JSON)
282
  @Path("/{referenceId}/irbDocument")
283
  @RolesAllowed({RESEARCHER})
284
  public Response uploadIrbDocument(
285
      @Auth AuthUser authUser,
286
      @PathParam("referenceId") String referenceId,
287
      @FormDataParam("file") InputStream uploadInputStream,
288
      @FormDataParam("file") FormDataContentDisposition fileDetail) {
289
    try {
290
      User user = findUserByEmail(authUser.getEmail());
1✔
291
      DataAccessRequest dar = getDarById(referenceId);
1✔
292
      checkAuthorizedUpdateUser(user, dar);
1✔
293
      DataAccessRequest updatedDar = updateDarWithDocumentContents(DarDocumentType.IRB, user, dar,
1✔
294
          uploadInputStream, fileDetail);
295
      return Response.ok(updatedDar.convertToSimplifiedDar()).build();
1✔
296
    } catch (Exception e) {
1✔
297
      return createExceptionResponse(e);
1✔
298
    }
299
  }
300

301
  @POST
302
  @Consumes(MediaType.MULTIPART_FORM_DATA)
303
  @Produces(MediaType.APPLICATION_JSON)
304
  @Path("/progress_report/{parentReferenceId}")
305
  @RolesAllowed({RESEARCHER})
306
  public Response postProgressReport(
307
      @Auth AuthUser authUser,
308
      @PathParam("parentReferenceId") String parentReferenceId,
309
      @FormDataParam("dar") String dar,
310
      @FormDataParam("collaboratorRequiredFile") InputStream collabInputStream,
311
      @FormDataParam("collaboratorRequiredFile") FormDataContentDisposition collabFileDetails,
312
      @FormDataParam("ethicsApprovalRequiredFile") InputStream ethicsInputStream,
313
      @FormDataParam("ethicsApprovalRequiredFile") FormDataContentDisposition ethicsFileDetails) {
314
    User user = userService.findUserByEmail(authUser.getEmail());
1✔
315
    DataAccessRequest parentDar = dataAccessRequestService.findByReferenceId(parentReferenceId);
1✔
316
    checkAuthorizedUpdateUser(user, parentDar);
1✔
317
    DataAccessRequest payload = populateDarFromJsonString(user, dar);
1✔
318
    DataAccessRequest childDar = dataAccessRequestService.createDataAccessRequest(user, payload);
1✔
319

320
    for (Integer datasetId : childDar.getDatasetIds()) {
1✔
321
      Dataset dataset = datasetService.findDatasetById(datasetId);
1✔
322
      if (dataset == null) {
1✔
323
        throw new NotFoundException("Dataset " + datasetId + " not found");
1✔
324
      }
325
      DataUse dataUse = dataset.getDataUse();
1✔
326
      if (dataUse == null || dataUse.getCollaboratorRequired() == null
1✔
327
          || dataUse.getEthicsApprovalRequired() == null) {
1✔
328
        throw new BadRequestException("Dataset " + datasetId + " is missing data use(s)");
1✔
329
      }
330
      if (dataUse.getCollaboratorRequired()) {
1✔
331
        String parentCollabLocation = parentDar.getData().getCollaborationLetterLocation();
1✔
332
        if ((collabFileDetails == null || collabFileDetails.getSize() <= 0)
1✔
333
            && Strings.isNullOrEmpty(parentCollabLocation)) {
1✔
334
          throw new BadRequestException("Collaboration document is required");
1✔
335
        }
336
        try {
337
          childDar = updateDarWithDocumentContents(DarDocumentType.COLLABORATION, user, childDar,
1✔
338
              collabInputStream, collabFileDetails);
339
        } catch (IOException e) {
×
340
          return createExceptionResponse(e);
×
341
        }
1✔
342
      }
343
      if (dataUse.getEthicsApprovalRequired()) {
1✔
344
        String parentEthicsLocation = parentDar.getData().getIrbDocumentLocation();
1✔
345
        if ((ethicsFileDetails == null || ethicsFileDetails.getSize() <= 0)
1✔
346
            && Strings.isNullOrEmpty(parentEthicsLocation)) {
1✔
347
          throw new BadRequestException("Ethics approval document is required");
×
348
        }
349
        try {
350
          childDar = updateDarWithDocumentContents(DarDocumentType.IRB, user, childDar,
1✔
351
              ethicsInputStream, ethicsFileDetails);
352
        } catch (IOException e) {
×
353
          return createExceptionResponse(e);
×
354
        }
1✔
355
      }
356
    }
1✔
357

358
    return Response.ok(childDar.convertToSimplifiedDar()).build();
1✔
359
  }
360

361
  @GET
362
  @Produces({MediaType.APPLICATION_OCTET_STREAM, MediaType.APPLICATION_JSON})
363
  @Path("/{referenceId}/collaborationDocument")
364
  @RolesAllowed({ADMIN, CHAIRPERSON, MEMBER, RESEARCHER})
365
  public Response getCollaborationDocument(
366
      @Auth AuthUser authUser,
367
      @PathParam("referenceId") String referenceId) {
368
    try {
369
      DataAccessRequest dar = getDarById(referenceId);
1✔
370
      validateAuthedRoleUser(
1✔
371
          Stream.of(UserRoles.ADMIN, UserRoles.CHAIRPERSON, UserRoles.MEMBER)
1✔
372
              .collect(Collectors.toList()),
1✔
373
          authUser, referenceId);
374
      if (dar.getData() != null &&
1✔
375
          StringUtils.isNotEmpty(dar.getData().getCollaborationLetterLocation()) &&
1✔
376
          StringUtils.isNotEmpty(dar.getData().getCollaborationLetterName())
1✔
377
      ) {
378
        String blobIdName = dar.getData().getCollaborationLetterLocation();
1✔
379
        String fileName = dar.getData().getCollaborationLetterName();
1✔
380
        InputStream is = gcsService.getDocument(blobIdName);
1✔
381
        StreamingOutput stream = createStreamingOutput(is);
1✔
382
        return Response.ok(stream)
1✔
383
            .header("Content-Disposition", "attachment; filename=" + fileName)
1✔
384
            .build();
1✔
385
      }
386
      throw new NotFoundException();
1✔
387
    } catch (Exception e) {
1✔
388
      return createExceptionResponse(e);
1✔
389
    }
390
  }
391

392
  @POST
393
  @Consumes(MediaType.MULTIPART_FORM_DATA)
394
  @Produces(MediaType.APPLICATION_JSON)
395
  @Path("/{referenceId}/collaborationDocument")
396
  @RolesAllowed({RESEARCHER})
397
  public Response uploadCollaborationDocument(
398
      @Auth AuthUser authUser,
399
      @PathParam("referenceId") String referenceId,
400
      @FormDataParam("file") InputStream uploadInputStream,
401
      @FormDataParam("file") FormDataContentDisposition fileDetail) {
402
    try {
403
      User user = findUserByEmail(authUser.getEmail());
1✔
404
      DataAccessRequest dar = getDarById(referenceId);
1✔
405
      checkAuthorizedUpdateUser(user, dar);
1✔
406
      DataAccessRequest updatedDar = updateDarWithDocumentContents(DarDocumentType.COLLABORATION,
1✔
407
          user, dar, uploadInputStream, fileDetail);
408
      return Response.ok(updatedDar.convertToSimplifiedDar()).build();
1✔
409
    } catch (Exception e) {
1✔
410
      return createExceptionResponse(e);
1✔
411
    }
412
  }
413

414
  @DELETE
415
  @Path("/{referenceId}")
416
  @Produces("application/json")
417
  @RolesAllowed({ADMIN, RESEARCHER})
418
  public Response deleteDar(@Auth AuthUser authUser, @PathParam("referenceId") String referenceId) {
419
    validateAuthedRoleUser(Collections.singletonList(UserRoles.ADMIN), authUser, referenceId);
×
420
    try {
421
      User user = findUserByEmail(authUser.getEmail());
×
422
      dataAccessRequestService.deleteByReferenceId(user, referenceId);
×
423
      return Response.ok().build();
×
424
    } catch (Exception e) {
×
425
      return createExceptionResponse(e);
×
426
    }
427
  }
428

429
  private User findUserByEmail(String email) {
430
    User user = userService.findUserByEmail(email);
1✔
431
    if (user == null) {
1✔
432
      throw new NotFoundException("Unable to find User with the provided email: " + email);
×
433
    }
434
    return user;
1✔
435
  }
436

437
  private DataAccessRequest populateDarFromJsonString(User user, String json) {
438
    DataAccessRequest newDar = new DataAccessRequest();
1✔
439
    DataAccessRequestData data;
440
    try {
441
      data = DataAccessRequestData.fromString(json);
1✔
442
    } catch (Exception e) {
1✔
443
      throw new BadRequestException("Unable to parse DAR from JSON string");
1✔
444
    }
1✔
445
    if (Objects.isNull(data)) {
1✔
446
      data = new DataAccessRequestData();
1✔
447
    }
448
    // When posting a submitted dar, there are two cases:
449
    // 1. those that existed previously as a draft dar
450
    // 2. those that are brand new
451
    // Validate the provided referenceId with the authenticated user and draft status
452
    // Those that do not validate are considered a brand new dar
453
    if (Objects.nonNull(data.getReferenceId())) {
1✔
454
      DataAccessRequest existingDar =
×
455
          dataAccessRequestService.findByReferenceId(data.getReferenceId());
×
456
      if (Objects.nonNull(existingDar)
×
457
          && existingDar.getUserId().equals(user.getUserId())
×
458
          && existingDar.getDraft()) {
×
459
        newDar.setReferenceId(data.getReferenceId());
×
460

461
        // if dar was part of a collection, we should use the same collection.
462
        if (Objects.nonNull(existingDar.getCollectionId())) {
×
463
          newDar.setCollectionId(existingDar.getCollectionId());
×
464
        }
465
      } else {
466
        String referenceId = UUID.randomUUID().toString();
×
467
        newDar.setReferenceId(referenceId);
×
468
        data.setReferenceId(referenceId);
×
469
      }
470
    } else {
×
471
      String referenceId = UUID.randomUUID().toString();
1✔
472
      newDar.setReferenceId(referenceId);
1✔
473
      data.setReferenceId(referenceId);
1✔
474
    }
475
    newDar.setData(data);
1✔
476
    newDar.addDatasetIds(data.getDatasetIds());
1✔
477
    return newDar;
1✔
478
  }
479

480
  private void checkAuthorizedUpdateUser(User user, DataAccessRequest dar) {
481
    if (!user.getUserId().equals(dar.getUserId())) {
1✔
482
      throw new ForbiddenException("User not authorized to update this Data Access Request");
1✔
483
    }
484
  }
1✔
485

486
  private DataAccessRequest updateDarWithDocumentContents(
487
      DarDocumentType type,
488
      User user,
489
      DataAccessRequest dar,
490
      InputStream uploadInputStream,
491
      FormDataContentDisposition fileDetail) throws IOException {
492
    validateFileDetails(fileDetail);
1✔
493
    String fileName = fileDetail.getFileName();
1✔
494
    UUID id = UUID.randomUUID();
1✔
495
    BlobId blobId = gcsService.storeDocument(uploadInputStream, fileDetail.getType(), id);
1✔
496
    switch (type) {
1✔
497
      case IRB:
498
        // Delete the current document if it exists
499
        if (Objects.nonNull(dar.getData().getIrbDocumentLocation())) {
1✔
500
          deleteDarDocument(dar, dar.getData().getIrbDocumentLocation());
1✔
501
        }
502
        dar.getData().setIrbDocumentLocation(blobId.getName());
1✔
503
        dar.getData().setIrbDocumentName(fileName);
1✔
504
        break;
1✔
505
      case COLLABORATION:
506
        // Delete the current document if it exists
507
        if (Objects.nonNull(dar.getData().getCollaborationLetterLocation())) {
1✔
508
          deleteDarDocument(dar, dar.getData().getCollaborationLetterLocation());
1✔
509
        }
510
        dar.getData().setCollaborationLetterLocation(blobId.getName());
1✔
511
        dar.getData().setCollaborationLetterName(fileName);
1✔
512
        break;
1✔
513
      default:
514
        break;
515
    }
516
    return dataAccessRequestService.updateByReferenceId(user, dar);
1✔
517
  }
518

519
  private void deleteDarDocument(DataAccessRequest dar, String blobIdName) {
520
    try {
521
      gcsService.deleteDocument(blobIdName);
1✔
522
    } catch (Exception e) {
×
523
      String message = String.format(
×
524
          "Unable to delete document for DAR ID: %s; dar document location: %s",
525
          dar.getReferenceId(), blobIdName);
×
526
      logWarn(message);
×
527
    }
1✔
528
  }
1✔
529

530
  private DataAccessRequest getDarById(String referenceId) {
531
    DataAccessRequest dar = dataAccessRequestService.findByReferenceId(referenceId);
1✔
532
    if (Objects.isNull(dar)) {
1✔
533
      throw new NotFoundException();
1✔
534
    }
535
    return dar;
1✔
536
  }
537

538
  /**
539
   * Custom handler for validating that a user can access a DAR. User will have access if ANY of
540
   * these conditions are met: If the DAR create user is the same as the Auth User, then the user
541
   * can access the resource. If the user has any of the roles in allowableRoles, then the user can
542
   * access the resource. In practice, pass in allowableRoles for users that are not the create user
543
   * (i.e. Admin) so they can also have access to the DAR.
544
   *
545
   * @param allowableRoles List of roles that would allow the user to access the resource
546
   * @param authUser       The AuthUser
547
   * @param referenceId    The referenceId of the resource.
548
   */
549
  private void validateAuthedRoleUser(final List<UserRoles> allowableRoles, AuthUser authUser,
550
      String referenceId) {
551
    DataAccessRequest dataAccessRequest = getDarById(referenceId);
1✔
552
    User user = findUserByEmail(authUser.getEmail());
1✔
553
    if (Objects.nonNull(dataAccessRequest.getUserId()) && dataAccessRequest.getUserId() > 0) {
1✔
554
      super.validateAuthedRoleUser(allowableRoles, user, dataAccessRequest.getUserId());
1✔
555
    } else {
556
      logWarn("DataAccessRequest '" + referenceId + "' has an invalid userId");
×
557
      super.validateAuthedRoleUser(allowableRoles, user, dataAccessRequest.getUserId());
×
558
    }
559
  }
1✔
560
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc