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

DataBiosphere / consent / #4467

18 Aug 2023 01:43PM UTC coverage: 76.439% (-0.03%) from 76.465%
#4467

push

web-flow
DUOS-2610 - Approved User Datasets API endpoint (#2113)

* WIP

* added example

* WIP

* WIP

* WIP

* completed api docs

* WIP

* WIP

* WIP'

* fixed SQL query bug

* reverted changes to DarCollectionDAO

* reverted changes to DarCollectionDAO

* added datasetDAO test

* added more test cases

* all tests work

* fixed bugs

* added user resource and dataset service tests

54 of 54 new or added lines in 5 files covered. (100.0%)

9681 of 12665 relevant lines covered (76.44%)

0.76 hits per line

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

88.94
/src/main/java/org/broadinstitute/consent/http/resources/UserResource.java
1
package org.broadinstitute.consent.http.resources;
2

3

4
import com.google.api.client.http.HttpStatusCodes;
5
import com.google.common.annotations.VisibleForTesting;
6
import com.google.gson.Gson;
7
import com.google.gson.JsonObject;
8
import com.google.gson.reflect.TypeToken;
9
import com.google.inject.Inject;
10
import io.dropwizard.auth.Auth;
11
import jakarta.ws.rs.BadRequestException;
12
import jakarta.ws.rs.Consumes;
13
import jakarta.ws.rs.DELETE;
14
import jakarta.ws.rs.ForbiddenException;
15
import jakarta.ws.rs.GET;
16
import jakarta.ws.rs.NotFoundException;
17
import jakarta.ws.rs.POST;
18
import jakarta.ws.rs.PUT;
19
import jakarta.ws.rs.Path;
20
import jakarta.ws.rs.PathParam;
21
import jakarta.ws.rs.Produces;
22
import jakarta.ws.rs.core.Context;
23
import jakarta.ws.rs.core.MediaType;
24
import jakarta.ws.rs.core.Response;
25
import jakarta.ws.rs.core.UriInfo;
26
import java.lang.reflect.Type;
27
import java.net.URI;
28
import java.util.ArrayList;
29
import java.util.Collections;
30
import java.util.List;
31
import java.util.Map;
32
import java.util.Objects;
33
import java.util.Optional;
34
import java.util.Set;
35
import java.util.stream.Collectors;
36
import javax.annotation.security.PermitAll;
37
import javax.annotation.security.RolesAllowed;
38
import org.broadinstitute.consent.http.authentication.GenericUser;
39
import org.broadinstitute.consent.http.enumeration.UserRoles;
40
import org.broadinstitute.consent.http.models.Acknowledgement;
41
import org.broadinstitute.consent.http.models.ApprovedDataset;
42
import org.broadinstitute.consent.http.models.AuthUser;
43
import org.broadinstitute.consent.http.models.Dataset;
44
import org.broadinstitute.consent.http.models.Error;
45
import org.broadinstitute.consent.http.models.User;
46
import org.broadinstitute.consent.http.models.UserRole;
47
import org.broadinstitute.consent.http.models.UserUpdateFields;
48
import org.broadinstitute.consent.http.models.dto.DatasetDTO;
49
import org.broadinstitute.consent.http.service.AcknowledgementService;
50
import org.broadinstitute.consent.http.service.DatasetService;
51
import org.broadinstitute.consent.http.service.SupportRequestService;
52
import org.broadinstitute.consent.http.service.UserService;
53
import org.broadinstitute.consent.http.service.UserService.SimplifiedUser;
54
import org.broadinstitute.consent.http.service.sam.SamService;
55

56
@Path("api/user")
57
public class UserResource extends Resource {
58

59
  private final UserService userService;
60
  private final Gson gson = new Gson();
1✔
61
  private final SamService samService;
62
  private final DatasetService datasetService;
63
  private final SupportRequestService supportRequestService;
64
  private final AcknowledgementService acknowledgementService;
65

66
  @Inject
67
  public UserResource(SamService samService, UserService userService,
68
      DatasetService datasetService, SupportRequestService supportRequestService,
69
      AcknowledgementService acknowledgementService) {
1✔
70
    this.samService = samService;
1✔
71
    this.userService = userService;
1✔
72
    this.datasetService = datasetService;
1✔
73
    this.supportRequestService = supportRequestService;
1✔
74
    this.acknowledgementService = acknowledgementService;
1✔
75
  }
1✔
76

77
  @GET
78
  @Produces("application/json")
79
  @Path("/role/{roleName}")
80
  @RolesAllowed({ADMIN, SIGNINGOFFICIAL})
81
  public Response getUsers(@Auth AuthUser authUser, @PathParam("roleName") String roleName) {
82
    try {
83
      User user = userService.findUserByEmail(authUser.getEmail());
1✔
84
      boolean valid = UserRoles.isValidRole(roleName);
1✔
85
      if (valid) {
1✔
86
        //if there is a valid roleName but it is not SO or Admin then throw an exception
87
        if (!roleName.equals(UserRoles.ADMIN.getRoleName()) && !roleName.equals(
1✔
88
            UserRoles.SIGNINGOFFICIAL.getRoleName())) {
1✔
89
          throw new BadRequestException("Unsupported role name: " + roleName);
1✔
90
        }
91
        if (!user.hasUserRole(UserRoles.getUserRoleFromName(roleName))) {
1✔
92
          throw new NotFoundException(
1✔
93
              "User: " + user.getDisplayName() + ", does not have " + roleName + " role.");
1✔
94
        }
95
        List<User> users = userService.getUsersAsRole(user, roleName);
1✔
96
        return Response.ok().entity(users).build();
1✔
97
      } else {
98
        throw new BadRequestException("Invalid role name: " + roleName);
1✔
99
      }
100
    } catch (Exception e) {
1✔
101
      return createExceptionResponse(e);
1✔
102
    }
103
  }
104

105
  @GET
106
  @Path("/me")
107
  @Produces("application/json")
108
  @PermitAll
109
  public Response getUser(@Auth AuthUser authUser) {
110
    try {
111
      User user = userService.findUserByEmail(authUser.getEmail());
1✔
112
      if (Objects.isNull(authUser.getUserStatusInfo())) {
1✔
113
        samService.asyncPostRegistrationInfo(authUser);
1✔
114
      }
115
      JsonObject userJson = userService.findUserWithPropertiesByIdAsJsonObject(authUser,
1✔
116
          user.getUserId());
1✔
117
      return Response.ok(gson.toJson(userJson)).build();
1✔
118
    } catch (Exception e) {
×
119
      return createExceptionResponse(e);
×
120
    }
121
  }
122

123
  @Deprecated // Use getDatasetsFromUserDacsV2
124
  @GET
125
  @Path("/me/dac/datasets")
126
  @Produces("application/json")
127
  @RolesAllowed({CHAIRPERSON, MEMBER})
128
  public Response getDatasetsFromUserDacs(@Auth AuthUser authUser) {
129
    try {
130
      Set<DatasetDTO> datasets;
131
      User user = userService.findUserByEmail(authUser.getEmail());
×
132
      List<Integer> dacIds = user.getRoles().stream()
×
133
          .filter(r -> Objects.nonNull(r.getDacId()))
×
134
          .map(UserRole::getDacId)
×
135
          .collect(Collectors.toList());
×
136
      datasets = dacIds.isEmpty() ? Set.of() : datasetService.findDatasetsByDacIds(dacIds);
×
137
      return Response.ok().entity(datasets).build();
×
138
    } catch (Exception e) {
×
139
      return createExceptionResponse(e);
×
140
    }
141
  }
142

143
  @GET
144
  @Path("/me/dac/datasets/v2")
145
  @Produces("application/json")
146
  @RolesAllowed({CHAIRPERSON, MEMBER})
147
  public Response getDatasetsFromUserDacsV2(@Auth AuthUser authUser) {
148
    try {
149
      User user = userService.findUserByEmail(authUser.getEmail());
1✔
150
      List<Integer> dacIds = user.getRoles().stream()
1✔
151
          .map(UserRole::getDacId)
1✔
152
          .filter(Objects::nonNull)
1✔
153
          .collect(Collectors.toList());
1✔
154
      List<Dataset> datasets =
155
          dacIds.isEmpty() ? List.of() : datasetService.findDatasetListByDacIds(dacIds);
1✔
156
      if (datasets.isEmpty()) {
1✔
157
        throw new NotFoundException("No datasets found for current user");
1✔
158
      }
159
      return Response.ok().entity(datasets).build();
1✔
160
    } catch (Exception e) {
1✔
161
      return createExceptionResponse(e);
1✔
162
    }
163
  }
164

165
  @GET
166
  @Path("/{userId}")
167
  @Produces("application/json")
168
  @RolesAllowed({ADMIN, CHAIRPERSON, MEMBER})
169
  public Response getUserById(@Auth AuthUser authUser, @PathParam("userId") Integer userId) {
170
    try {
171
      JsonObject userJson = userService.findUserWithPropertiesByIdAsJsonObject(authUser, userId);
1✔
172
      return Response.ok(gson.toJson(userJson)).build();
1✔
173
    } catch (Exception e) {
1✔
174
      return createExceptionResponse(e);
1✔
175
    }
176
  }
177

178
  @GET
179
  @Path("/institution/unassigned")
180
  @Produces("application/json")
181
  @RolesAllowed({ADMIN, SIGNINGOFFICIAL})
182
  public Response getUnassignedUsers(@Auth AuthUser user) {
183
    try {
184
      List<User> unassignedUsers = userService.findUsersWithNoInstitution();
1✔
185
      return Response.ok().entity(unassignedUsers).build();
1✔
186
    } catch (Exception e) {
×
187
      return createExceptionResponse(e);
×
188
    }
189
  }
190

191
  @GET
192
  @Path("/institution/{institutionId}")
193
  @Produces("application/json")
194
  @RolesAllowed({ADMIN})
195
  public Response getUsersByInstitution(
196
      @Auth AuthUser user, @PathParam("institutionId") Integer institutionId) {
197
    try {
198
      List<User> users = userService.findUsersByInstitutionId(institutionId);
1✔
199
      return Response.ok().entity(users).build();
1✔
200
    } catch (Exception e) {
1✔
201
      return createExceptionResponse(e);
1✔
202
    }
203
  }
204

205
  @PUT
206
  @Path("/{id}")
207
  @Consumes("application/json")
208
  @Produces("application/json")
209
  @RolesAllowed({ADMIN})
210
  public Response update(@Auth AuthUser authUser, @Context UriInfo info,
211
      @PathParam("id") Integer userId, String json) {
212
    try {
213
      UserUpdateFields userUpdateFields = gson.fromJson(json, UserUpdateFields.class);
1✔
214
      // Ensure that we have a real user with this ID, fail if we do not.
215
      userService.findUserById(userId);
1✔
216
      User updatedUser = userService.updateUserFieldsById(userUpdateFields, userId);
1✔
217
      Gson gson = new Gson();
1✔
218
      JsonObject jsonUser = userService.findUserWithPropertiesByIdAsJsonObject(authUser,
1✔
219
          updatedUser.getUserId());
1✔
220
      return Response.ok().entity(gson.toJson(jsonUser)).build();
1✔
221
    } catch (Exception e) {
1✔
222
      return createExceptionResponse(e);
1✔
223
    }
224
  }
225

226
  @PUT
227
  @Consumes("application/json")
228
  @Produces("application/json")
229
  @PermitAll
230
  public Response updateSelf(@Auth AuthUser authUser, @Context UriInfo info, String json) {
231
    try {
232
      User user = userService.findUserByEmail(authUser.getEmail());
1✔
233
      UserUpdateFields userUpdateFields = gson.fromJson(json, UserUpdateFields.class);
1✔
234

235
      if (Objects.nonNull(userUpdateFields.getUserRoleIds()) && !user.hasUserRole(
1✔
236
          UserRoles.ADMIN)) {
237
        throw new BadRequestException("Cannot change user's roles.");
1✔
238
      }
239

240
      if (!canUpdateInstitution(user, userUpdateFields.getInstitutionId())) {
1✔
241
        throw new BadRequestException("Cannot update user's institution id.");
1✔
242
      }
243

244
      user = userService.updateUserFieldsById(userUpdateFields, user.getUserId());
1✔
245
      supportRequestService.handleInstitutionSOSupportRequest(userUpdateFields, user);
1✔
246
      Gson gson = new Gson();
1✔
247
      JsonObject jsonUser = userService.findUserWithPropertiesByIdAsJsonObject(authUser,
1✔
248
          user.getUserId());
1✔
249

250
      return Response.ok().entity(gson.toJson(jsonUser)).build();
1✔
251
    } catch (Exception e) {
1✔
252
      return createExceptionResponse(e);
1✔
253
    }
254
  }
255

256
  @VisibleForTesting
257
  protected boolean canUpdateInstitution(User user, Integer newInstitutionId) {
258
    if ((!Objects.isNull(user.getUserId()) || !Objects.isNull(newInstitutionId)) && !Objects.equals(
1✔
259
        user.getInstitutionId(), newInstitutionId)) {
1✔
260
      if (user.hasUserRole(UserRoles.ADMIN)) {
1✔
261
        return true; // admins can do everything.
1✔
262
      }
263
      if (user.hasUserRole(UserRoles.SIGNINGOFFICIAL) || user.hasUserRole(UserRoles.ITDIRECTOR)) {
1✔
264
        // can only update institution if not set.
265
        return Objects.isNull(user.getInstitutionId()) && Objects.nonNull(newInstitutionId);
1✔
266
      }
267
      // User is not restricted based on role
268
      return true;
1✔
269
    } else {
270
      return true; // no op, no change, supports keeping no institution set to no institution.
1✔
271
    }
272
  }
273

274
  @PUT
275
  @Path("/{userId}/{roleId}")
276
  @Produces("application/json")
277
  @RolesAllowed({ADMIN, SIGNINGOFFICIAL})
278
  public Response addRoleToUser(@Auth AuthUser authUser, @PathParam("userId") Integer userId,
279
      @PathParam("roleId") Integer roleId) {
280
    UserRoles targetRole = UserRoles.getUserRoleFromId(roleId);
1✔
281
    if (Objects.isNull(targetRole)) {
1✔
282
      return Response.status(HttpStatusCodes.STATUS_CODE_BAD_REQUEST).build();
1✔
283
    }
284
    UserRole role = new UserRole(roleId, targetRole.getRoleName());
1✔
285
    try {
286
      User activeUser = userService.findUserByEmail(authUser.getEmail());
1✔
287
      User user = userService.findUserById(userId);
1✔
288
      List<Integer> currentUserRoleIds = user.getUserRoleIdsFromUser();
1✔
289
      if (activeUser.hasUserRole(UserRoles.ADMIN) && UserRoles.isValidNonDACRoleId(roleId)) {
1✔
290
        if (!currentUserRoleIds.contains(roleId)) {
1✔
291
          userService.insertUserRoles(Collections.singletonList(role), user.getUserId());
1✔
292
          return getUserResponse(authUser, userId);
1✔
293
        } else {
294
          return Response.notModified().build();
1✔
295
        }
296
      } else if (signingOfficialMeetsRequirements(roleId, activeUser, user)) {
1✔
297
        // update the user role with the active user's institution id.
298
        if (!currentUserRoleIds.contains(roleId)) {
1✔
299
          // update the user's institution if it was set to null and add the role.
300
          if (Optional.ofNullable(user.getInstitutionId()).isEmpty()) {
1✔
301
            userService.insertRoleAndInstitutionForUser(role, activeUser.getInstitutionId(),
1✔
302
                user.getUserId());
1✔
303
          } else {
304
            userService.insertUserRoles(Collections.singletonList(role), user.getUserId());
1✔
305
          }
306
          return getUserResponse(authUser, userId);
1✔
307
        } else {
308
          return Response.notModified().build();
×
309
        }
310
      } else {
311
        return Response.status(HttpStatusCodes.STATUS_CODE_BAD_REQUEST).build();
1✔
312
      }
313
    } catch (Exception e) {
1✔
314
      return createExceptionResponse(e);
1✔
315
    }
316
  }
317

318
  private static boolean signingOfficialMeetsRequirements(Integer roleId, User activeUser,
319
      User user) {
320
    return activeUser.hasUserRole(UserRoles.SIGNINGOFFICIAL)
1✔
321
        && Objects.nonNull(activeUser.getInstitutionId())
1✔
322
        && UserRoles.isValidSoAdjustableRoleId(roleId)
1✔
323
        && (Objects.equals(user.getInstitutionId(), activeUser.getInstitutionId()) ||
1✔
324
        Optional.ofNullable(user.getInstitutionId()).isEmpty());
1✔
325
  }
326

327
  private Response getUserResponse(AuthUser authUser, Integer userId) {
328
    JsonObject userJson = userService.findUserWithPropertiesByIdAsJsonObject(authUser, userId);
1✔
329
    return Response.ok().entity(gson.toJson(userJson)).build();
1✔
330
  }
331

332
  @DELETE
333
  @Path("/{userId}/{roleId}")
334
  @Produces("application/json")
335
  @RolesAllowed({ADMIN, SIGNINGOFFICIAL})
336
  public Response deleteRoleFromUser(@Auth AuthUser authUser, @PathParam("userId") Integer userId,
337
      @PathParam("roleId") Integer roleId) {
338
    UserRoles targetRole = UserRoles.getUserRoleFromId(roleId);
1✔
339
    if (Objects.isNull(targetRole)) {
1✔
340
      return Response.status(HttpStatusCodes.STATUS_CODE_BAD_REQUEST).build();
1✔
341
    }
342
    try {
343
      User activeUser = userService.findUserByEmail(authUser.getEmail());
1✔
344
      User user = userService.findUserById(userId);
1✔
345
      if (activeUser.hasUserRole(UserRoles.ADMIN)) {
1✔
346
        if (!UserRoles.isValidNonDACRoleId(roleId)) {
1✔
347
          throw new BadRequestException("Invalid Role Id");
×
348
        }
349
        return doDelete(authUser, userId, roleId, activeUser, user);
1✔
350
      } else if (activeUser.hasUserRole(UserRoles.SIGNINGOFFICIAL)) {
1✔
351
        if (!UserRoles.isValidSoAdjustableRoleId(roleId)) {
1✔
352
          throw new ForbiddenException(
1✔
353
              "A Signing Official may only remove the following role ids: [6, 7, 8] ");
354
        }
355
        if (Objects.equals(user.getUserId(), activeUser.getUserId())
1✔
356
            && (UserRoles.getUserRoleFromId(roleId) == UserRoles.SIGNINGOFFICIAL)) {
1✔
357
          throw new BadRequestException(
1✔
358
              "You cannot remove the SIGNINGOFFICIAL role from yourself.");
359
        }
360
        if (Objects.nonNull(activeUser.getInstitutionId())
1✔
361
            && Objects.equals(activeUser.getInstitutionId(), user.getInstitutionId())) {
1✔
362
          return doDelete(authUser, userId, roleId, activeUser, user);
1✔
363
        } else {
364
          throw new ForbiddenException("Not authorized to remove roles");
1✔
365
        }
366
      } else {
367
        throw new ForbiddenException("Not authorized to remove roles.");
×
368
      }
369
    } catch (Exception e) {
1✔
370
      return createExceptionResponse(e);
1✔
371
    }
372
  }
373

374
  private Response doDelete(AuthUser authUser, Integer userId, Integer roleId, User activeUser,
375
      User user) {
376
    List<Integer> currentUserRoleIds = user.getUserRoleIdsFromUser();
1✔
377
    if (!currentUserRoleIds.contains(roleId)) {
1✔
378
      JsonObject userJson = userService.findUserWithPropertiesByIdAsJsonObject(authUser, userId);
1✔
379
      return Response.ok().entity(gson.toJson(userJson)).build();
1✔
380
    }
381
    userService.deleteUserRole(activeUser, userId, roleId);
1✔
382
    JsonObject userJson = userService.findUserWithPropertiesByIdAsJsonObject(authUser, userId);
1✔
383
    return Response.ok().entity(gson.toJson(userJson)).build();
1✔
384
  }
385

386
  @POST
387
  @Consumes("application/json")
388
  @Produces("application/json")
389
  @PermitAll
390
  public Response createResearcher(@Context UriInfo info, @Auth AuthUser user) {
391
    GenericUser genericUser = user.getGenericUser();
1✔
392
    if (genericUser == null || genericUser.getEmail() == null || genericUser.getName() == null) {
1✔
393
      return Response.
1✔
394
          status(Response.Status.BAD_REQUEST).
1✔
395
          entity(new Error("Unable to verify google identity",
1✔
396
              Response.Status.BAD_REQUEST.getStatusCode())).
1✔
397
          build();
1✔
398
    }
399
    try {
400
      if (userService.findUserByEmail(genericUser.getEmail()) != null) {
1✔
401
        return Response.
1✔
402
            status(Response.Status.CONFLICT).
1✔
403
            entity(new Error("Registered user exists", Response.Status.CONFLICT.getStatusCode())).
1✔
404
            build();
1✔
405
      }
406
    } catch (NotFoundException nfe) {
1✔
407
      // no-op, we expect to not find the new user in this case.
408
    }
×
409
    User dacUser = new User(genericUser);
1✔
410
    UserRole researcher = new UserRole(UserRoles.RESEARCHER.getRoleId(),
1✔
411
        UserRoles.RESEARCHER.getRoleName());
1✔
412
    dacUser.setRoles(Collections.singletonList(researcher));
1✔
413
    try {
414
      URI uri;
415
      dacUser = userService.createUser(dacUser);
1✔
416
      uri = info.getRequestUriBuilder().path("{email}").build(dacUser.getEmail());
1✔
417
      return Response.created(new URI(uri.toString().replace("user", "dacuser"))).entity(dacUser)
1✔
418
          .build();
1✔
419
    } catch (Exception e) {
×
420
      return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
×
421
          .entity(new Error(e.getMessage(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()))
×
422
          .build();
×
423
    }
424
  }
425

426
  @DELETE
427
  @Produces(MediaType.APPLICATION_JSON)
428
  @Path("/{email}")
429
  @RolesAllowed(ADMIN)
430
  public Response delete(@PathParam("email") String email, @Context UriInfo info) {
431
    userService.deleteUserByEmail(email);
1✔
432
    return Response.ok().build();
1✔
433
  }
434

435
  @GET
436
  @Produces(MediaType.APPLICATION_JSON)
437
  @Path("/signing-officials")
438
  @RolesAllowed(RESEARCHER)
439
  public Response getSOsForInstitution(@Auth AuthUser authUser) {
440
    try {
441
      User user = userService.findUserByEmail(authUser.getEmail());
1✔
442
      if (Objects.nonNull(user.getInstitutionId())) {
1✔
443
        List<SimplifiedUser> signingOfficials = userService.findSOsByInstitutionId(
1✔
444
            user.getInstitutionId());
1✔
445
        return Response.ok().entity(signingOfficials).build();
1✔
446
      }
447
      return Response.ok().entity(Collections.emptyList()).build();
1✔
448
    } catch (Exception e) {
1✔
449
      return createExceptionResponse(e);
1✔
450
    }
451
  }
452

453
  @GET
454
  @Produces(MediaType.APPLICATION_JSON)
455
  @Path("/acknowledgements")
456
  @PermitAll
457
  public Response getUserAcknowledgements(@Auth AuthUser authUser) {
458
    try {
459
      User user = userService.findUserByEmail(authUser.getEmail());
1✔
460
      Map<String, Acknowledgement> acknowledgementMap = acknowledgementService.findAcknowledgementsForUser(
1✔
461
          user);
462
      return Response.ok().entity(acknowledgementMap).build();
1✔
463
    } catch (Exception e) {
1✔
464
      return createExceptionResponse(e);
1✔
465
    }
466
  }
467

468
  @GET
469
  @Produces(MediaType.APPLICATION_JSON)
470
  @Path("/acknowledgements/{key}")
471
  @PermitAll
472
  public Response getUserAcknowledgement(@Auth AuthUser authUser, @PathParam("key") String key) {
473
    try {
474
      User user = userService.findUserByEmail(authUser.getEmail());
1✔
475
      Acknowledgement ack = acknowledgementService.findAcknowledgementForUserByKey(user, key);
1✔
476
      if (ack == null) {
1✔
477
        return Response.status(Response.Status.NOT_FOUND).build();
1✔
478
      }
479
      return Response.ok().entity(ack).build();
1✔
480
    } catch (Exception e) {
1✔
481
      return createExceptionResponse(e);
1✔
482
    }
483
  }
484

485
  @DELETE
486
  @Produces(MediaType.APPLICATION_JSON)
487
  @Path("/acknowledgements/{key}")
488
  @RolesAllowed(ADMIN)
489
  public Response deleteUserAcknowledgement(@Auth AuthUser authUser, @PathParam("key") String key) {
490
    try {
491
      User user = userService.findUserByEmail(authUser.getEmail());
1✔
492
      Acknowledgement ack = acknowledgementService.findAcknowledgementForUserByKey(user, key);
1✔
493
      if (Objects.isNull(ack)) {
1✔
494
        return Response.status(Response.Status.NOT_FOUND).build();
1✔
495
      }
496
      acknowledgementService.deleteAcknowledgementForUserByKey(user, key);
1✔
497
      return Response.ok().entity(ack).build();
1✔
498
    } catch (Exception e) {
×
499
      return createExceptionResponse(e);
×
500
    }
501
  }
502

503
  @POST
504
  @Consumes(MediaType.APPLICATION_JSON)
505
  @Produces(MediaType.APPLICATION_JSON)
506
  @Path("/acknowledgements")
507
  @PermitAll
508
  public Response postAcknowledgements(@Auth AuthUser authUser, String json) {
509
    ArrayList<String> keys;
510
    try {
511
      Type listOfStringsType = new TypeToken<ArrayList<String>>() {
1✔
512
      }.getType();
1✔
513
      keys = gson.fromJson(json, listOfStringsType);
1✔
514
      if (keys == null || keys.isEmpty()) {
1✔
515
        return Response.status(Response.Status.BAD_REQUEST).build();
1✔
516
      }
517
    } catch (Exception e) {
1✔
518
      return Response.status(Response.Status.BAD_REQUEST).build();
1✔
519
    }
1✔
520

521
    try {
522
      User user = userService.findUserByEmail(authUser.getEmail());
1✔
523
      Map<String, Acknowledgement> acknowledgementMap = acknowledgementService.makeAcknowledgements(
1✔
524
          keys, user);
525
      return Response.ok().entity(acknowledgementMap).build();
1✔
526
    } catch (Exception e) {
1✔
527
      return createExceptionResponse(e);
1✔
528
    }
529
  }
530

531
  @GET
532
  @Produces(MediaType.APPLICATION_JSON)
533
  @Path("/me/researcher/datasets")
534
  @PermitAll
535
  public Response getApprovedDatasets(@Auth AuthUser authUser) {
536
    try {
537
      User user = userService.findUserByEmail(authUser.getEmail());
1✔
538
      List<ApprovedDataset> approvedDatasets = datasetService.getApprovedDatasets(user);
1✔
539
      return Response.ok().entity(approvedDatasets).build();
1✔
540
    } catch (Exception e) {
×
541
      return createExceptionResponse(e);
×
542
    }
543
  }
544

545

546
}
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

© 2026 Coveralls, Inc