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

DataBiosphere / consent / #5727

23 Apr 2025 07:27PM UTC coverage: 79.087% (+0.07%) from 79.021%
#5727

push

web-flow
[DT-1545] Block submitted dars from being modified. (#2495)

38 of 40 new or added lines in 5 files covered. (95.0%)

10271 of 12987 relevant lines covered (79.09%)

0.79 hits per line

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

89.01
/src/main/java/org/broadinstitute/consent/http/service/UserService.java
1
package org.broadinstitute.consent.http.service;
2

3
import static org.broadinstitute.consent.http.enumeration.UserFields.ERA_EXPIRATION_DATE;
4
import static org.broadinstitute.consent.http.enumeration.UserFields.ERA_STATUS;
5

6
import com.google.gson.Gson;
7
import com.google.gson.JsonArray;
8
import com.google.gson.JsonElement;
9
import com.google.gson.JsonObject;
10
import com.google.inject.Inject;
11
import jakarta.ws.rs.BadRequestException;
12
import jakarta.ws.rs.NotFoundException;
13
import java.util.Collections;
14
import java.util.Date;
15
import java.util.List;
16
import java.util.Objects;
17
import java.util.Optional;
18
import java.util.stream.Collectors;
19
import java.util.stream.Stream;
20
import org.apache.commons.collections4.CollectionUtils;
21
import org.apache.commons.lang3.StringUtils;
22
import org.broadinstitute.consent.http.db.AcknowledgementDAO;
23
import org.broadinstitute.consent.http.db.DaaDAO;
24
import org.broadinstitute.consent.http.db.FileStorageObjectDAO;
25
import org.broadinstitute.consent.http.db.InstitutionDAO;
26
import org.broadinstitute.consent.http.db.LibraryCardDAO;
27
import org.broadinstitute.consent.http.db.SamDAO;
28
import org.broadinstitute.consent.http.db.UserDAO;
29
import org.broadinstitute.consent.http.db.UserPropertyDAO;
30
import org.broadinstitute.consent.http.db.UserRoleDAO;
31
import org.broadinstitute.consent.http.db.VoteDAO;
32
import org.broadinstitute.consent.http.enumeration.UserFields;
33
import org.broadinstitute.consent.http.enumeration.UserRoles;
34
import org.broadinstitute.consent.http.exceptions.ConsentConflictException;
35
import org.broadinstitute.consent.http.models.AuthUser;
36
import org.broadinstitute.consent.http.models.DataAccessAgreement;
37
import org.broadinstitute.consent.http.models.Institution;
38
import org.broadinstitute.consent.http.models.LibraryCard;
39
import org.broadinstitute.consent.http.models.User;
40
import org.broadinstitute.consent.http.models.UserProperty;
41
import org.broadinstitute.consent.http.models.UserRole;
42
import org.broadinstitute.consent.http.models.UserUpdateFields;
43
import org.broadinstitute.consent.http.models.Vote;
44
import org.broadinstitute.consent.http.resources.Resource;
45
import org.broadinstitute.consent.http.service.dao.DraftServiceDAO;
46
import org.broadinstitute.consent.http.service.dao.UserServiceDAO;
47
import org.broadinstitute.consent.http.util.ConsentLogger;
48
import org.broadinstitute.consent.http.util.gson.GsonUtil;
49

50
public class UserService implements ConsentLogger {
51

52
  public static final String LIBRARY_CARDS_FIELD = "libraryCards";
53
  public static final String USER_PROPERTIES_FIELD = "properties";
54
  public static final String USER_STATUS_INFO_FIELD = "userStatusInfo";
55

56
  private final UserPropertyDAO userPropertyDAO;
57
  private final UserDAO userDAO;
58
  private final UserRoleDAO userRoleDAO;
59
  private final VoteDAO voteDAO;
60
  private final InstitutionDAO institutionDAO;
61
  private final LibraryCardDAO libraryCardDAO;
62
  private final AcknowledgementDAO acknowledgementDAO;
63
  private final FileStorageObjectDAO fileStorageObjectDAO;
64
  private final SamDAO samDAO;
65
  private final UserServiceDAO userServiceDAO;
66
  private final DaaDAO daaDAO;
67
  private final EmailService emailService;
68
  private final DraftServiceDAO draftServiceDAO;
69
  private final InstitutionService institutionService;
70

71
  @Inject
72
  public UserService(UserDAO userDAO, UserPropertyDAO userPropertyDAO, UserRoleDAO userRoleDAO,
73
      VoteDAO voteDAO, InstitutionDAO institutionDAO, LibraryCardDAO libraryCardDAO,
74
      AcknowledgementDAO acknowledgementDAO, FileStorageObjectDAO fileStorageObjectDAO,
75
      SamDAO samDAO, UserServiceDAO userServiceDAO, DaaDAO daaDAO, EmailService emailService,
76
      DraftServiceDAO draftServiceDAO, InstitutionService institutionService) {
1✔
77
    this.userDAO = userDAO;
1✔
78
    this.userPropertyDAO = userPropertyDAO;
1✔
79
    this.userRoleDAO = userRoleDAO;
1✔
80
    this.voteDAO = voteDAO;
1✔
81
    this.institutionDAO = institutionDAO;
1✔
82
    this.libraryCardDAO = libraryCardDAO;
1✔
83
    this.acknowledgementDAO = acknowledgementDAO;
1✔
84
    this.fileStorageObjectDAO = fileStorageObjectDAO;
1✔
85
    this.samDAO = samDAO;
1✔
86
    this.userServiceDAO = userServiceDAO;
1✔
87
    this.daaDAO = daaDAO;
1✔
88
    this.emailService = emailService;
1✔
89
    this.draftServiceDAO = draftServiceDAO;
1✔
90
    this.institutionService = institutionService;
1✔
91
  }
1✔
92

93
  /**
94
   * Update a select group of user fields for a user id.
95
   *
96
   * @param userUpdateFields A UserUpdateFields object for all update information
97
   * @param userId           The User's ID
98
   * @return The updated User
99
   */
100
  public User updateUserFieldsById(UserUpdateFields userUpdateFields, Integer userId) {
101
    if (Objects.nonNull(userUpdateFields)) {
1✔
102
      // Update Primary User Fields
103
      if (Objects.nonNull(userUpdateFields.getDisplayName())) {
1✔
104
        userDAO.updateDisplayName(userId, userUpdateFields.getDisplayName());
1✔
105
      }
106
      if (Objects.nonNull(userUpdateFields.getInstitutionId())) {
1✔
107
        userDAO.updateInstitutionId(userId, userUpdateFields.getInstitutionId());
1✔
108
      }
109
      if (Objects.nonNull(userUpdateFields.getEmailPreference())) {
1✔
110
        userDAO.updateEmailPreference(userId, userUpdateFields.getEmailPreference());
1✔
111
      }
112
      if (Objects.nonNull(userUpdateFields.getEraCommonsId())) {
1✔
113
        userDAO.updateEraCommonsId(userId, userUpdateFields.getEraCommonsId());
1✔
114
      }
115

116
      Optional<User> soBeforeUpdate = getSigningOfficialForUser(userId);
1✔
117

118
      // Update User Properties
119
      List<UserProperty> userProps = userUpdateFields.buildUserProperties(userId);
1✔
120
      if (!userProps.isEmpty()) {
1✔
121
        userPropertyDAO.deletePropertiesByUserAndKey(userProps);
1✔
122
        userPropertyDAO.insertAll(userProps);
1✔
123
      }
124

125
      Optional<User> soAfterUpdate = getSigningOfficialForUser(userId);
1✔
126

127
      // if SO went from not specified to specified (i.e. set for the first time)
128
      // then send an email
129
      if (soBeforeUpdate.isEmpty() && soAfterUpdate.isPresent()) {
1✔
130
        try {
131
          emailService.sendNewResearcherMessage(
1✔
132
              userDAO.findUserById(userId),
1✔
133
              soAfterUpdate.get()
1✔
134
          );
135
        } catch (Exception e) {
×
136
          logWarn("Could not send new researcher notification to SO: %s".formatted(e.getMessage()));
×
137
        }
1✔
138

139
      }
140

141
      // Handle Roles
142
      if (Objects.nonNull(userUpdateFields.getUserRoleIds())) {
1✔
143
        List<Integer> currentRoleIds = userRoleDAO.findRolesByUserId(userId).stream()
1✔
144
            .map(UserRole::getRoleId).collect(Collectors.toList());
1✔
145
        List<Integer> roleIdsToAdd = userUpdateFields.getRoleIdsToAdd(currentRoleIds);
1✔
146
        List<Integer> roleIdsToRemove = userUpdateFields.getRoleIdsToRemove(currentRoleIds);
1✔
147
        // Add the new role ids to the user
148
        if (!roleIdsToAdd.isEmpty()) {
1✔
149
          List<UserRole> newRoles = roleIdsToAdd.stream()
1✔
150
              .map(id -> new UserRole(id,
1✔
151
                  Objects.requireNonNull(UserRoles.getUserRoleFromId(id)).getRoleName()))
1✔
152
              .collect(Collectors.toList());
1✔
153
          userRoleDAO.insertUserRoles(newRoles, userId);
1✔
154
        }
155
        // Remove the old role ids from the user
156
        if (!roleIdsToRemove.isEmpty()) {
1✔
157
          userRoleDAO.removeUserRoles(userId, roleIdsToRemove);
1✔
158
        }
159
      }
160

161
    }
162
    return findUserById(userId);
1✔
163
  }
164

165
  public void insertRoleAndInstitutionForUser(UserRole role, User user) {
166
    var userId = user.getUserId();
1✔
167
    try {
168
      if (user.getInstitutionId() == null) {
1✔
169
        Institution institution = institutionService.findInstitutionForEmail(user.getEmail());
1✔
170
        if (institution == null) {
1✔
171
          throw new BadRequestException(
1✔
172
              "No institution found for user: %s".formatted(user.getEmail()));
1✔
173
        }
174
        userServiceDAO.insertRoleAndInstitutionTxn(role, institution.getId(), userId);
1✔
175
      } else {
1✔
176
        userRoleDAO.insertSingleUserRole(role.getRoleId(), userId);
1✔
177
      }
178
    } catch (Exception e) {
1✔
179
      logException(
1✔
180
          "Error when updating user: %s, role: %s".formatted(userId, role), e);
1✔
181
      throw e;
1✔
182
    }
1✔
183
  }
1✔
184

185
  public User createUser(User user) {
186
    // Default role is researcher.
187
    if (CollectionUtils.isEmpty(user.getRoles())) {
1✔
188
      user.setResearcherRole();
1✔
189
    }
190
    validateRequiredFields(user);
1✔
191
    User existingUser = userDAO.findUserByEmail(user.getEmail());
1✔
192
    if (Objects.nonNull(existingUser)) {
1✔
193
      throw new BadRequestException("User exists with this email address: " + user.getEmail());
1✔
194
    }
195
    Institution institution = institutionService.findInstitutionForEmail(user.getEmail());
1✔
196
    if (institution != null) {
1✔
197
      user.setInstitutionId(institution.getId());
1✔
198
    }
199
    Integer userId = userDAO.insertUser(user.getEmail(), user.getDisplayName(),
1✔
200
        user.getInstitutionId(), new Date());
1✔
201
    insertUserRoles(user.getRoles(), userId);
1✔
202
    addExistingLibraryCards(user);
1✔
203
    return userDAO.findUserById(userId);
1✔
204
  }
205

206
  public User findUserById(Integer id) throws NotFoundException {
207
    User user = userDAO.findUserById(id);
1✔
208
    if (user == null) {
1✔
209
      throw new NotFoundException("Unable to find user with id: " + id);
1✔
210
    }
211
    List<LibraryCard> cards = libraryCardDAO.findLibraryCardsByUserId(user.getUserId());
1✔
212
    if (Objects.nonNull(cards) && !cards.isEmpty()) {
1✔
213
      user.setLibraryCards(cards);
1✔
214
    }
215
    return user;
1✔
216
  }
217

218
  public User findUserByEmail(String email) throws NotFoundException {
219
    User user = userDAO.findUserByEmail(email);
1✔
220
    if (user == null) {
1✔
221
      throw new NotFoundException("Unable to find user with email: " + email);
1✔
222
    }
223
    List<LibraryCard> cards = libraryCardDAO.findLibraryCardsByUserId(user.getUserId());
1✔
224
    if (Objects.nonNull(cards) && !cards.isEmpty()) {
1✔
225
      user.setLibraryCards(cards);
×
226
    }
227
    return user;
1✔
228
  }
229

230
  /**
231
   * Find users as a specific role, e.g., Admins can see all users, other roles can only see a
232
   * subset of users.
233
   *
234
   * @param user     The user making the request
235
   * @param roleName The role the user is making the request as
236
   * @return List of Users for specified role name
237
   */
238
  public List<User> getUsersAsRole(User user, String roleName) {
239
    switch (roleName) {
1✔
240
      // SigningOfficial console is technically pulling LCs, it's just bringing associated users along for the ride
241
      // However LCs can be created for users not yet registered in the system
242
      // As such a more specialized query is needed to produce the proper listing
243
      case Resource.SIGNINGOFFICIAL:
244
        Integer institutionId = user.getInstitutionId();
1✔
245
        if (Objects.nonNull(user.getInstitutionId())) {
1✔
246
          return userDAO.getUsersFromInstitutionWithCards(institutionId);
1✔
247
        } else {
248
          throw new NotFoundException("Signing Official (user: " + user.getDisplayName()
1✔
249
              + ") is not associated with an Institution.");
250
        }
251
      case Resource.ADMIN:
252
        return userDAO.findUsersWithLCsAndInstitution();
1✔
253
      default:
254
        // do nothing
255
    }
256
    return Collections.emptyList();
×
257
  }
258

259
  public List<SimplifiedUser> getUsersByDaaId(Integer daaId) {
260
    if (Objects.isNull(daaId)) {
1✔
261
      throw new IllegalArgumentException();
×
262
    }
263
    DataAccessAgreement daa = daaDAO.findById(daaId);
1✔
264
    if (Objects.isNull(daa)) {
1✔
265
      throw new NotFoundException();
1✔
266
    }
267
    List<User> users = userDAO.getUsersWithCardsByDaaId(daaId);
1✔
268
    return users.stream().map(SimplifiedUser::new).collect(Collectors.toList());
1✔
269
  }
270

271
  public void deleteUserByEmail(String email) {
272
    User user = userDAO.findUserByEmail(email);
1✔
273
    if (user == null) {
1✔
274
      throw new NotFoundException("The user for the specified E-Mail address does not exist");
×
275
    }
276
    Integer userId = user.getUserId();
1✔
277
    List<Integer> roleIds = userRoleDAO.
1✔
278
        findRolesByUserId(userId).
1✔
279
        stream().
1✔
280
        map(UserRole::getRoleId).
1✔
281
        collect(Collectors.toList());
1✔
282
    if (!roleIds.isEmpty()) {
1✔
283
      userRoleDAO.removeUserRoles(userId, roleIds);
×
284
    }
285
    List<Vote> votes = voteDAO.findVotesByUserId(userId);
1✔
286
    if (!votes.isEmpty()) {
1✔
287
      List<Integer> voteIds = votes.stream().map(Vote::getVoteId).collect(Collectors.toList());
×
288
      voteDAO.removeVotesByIds(voteIds);
×
289
    }
290
    try {
291
      draftServiceDAO.deleteDraftsByUser(user);
1✔
292
    } catch (Exception e) {
×
293
      logException(
×
294
          String.format("Unable to delete all drafts and files for userId %d. Error was: %s",
×
295
              userId, e.getMessage()), e);
×
296
    }
1✔
297
    institutionDAO.deleteAllInstitutionsByUser(userId);
1✔
298
    userPropertyDAO.deleteAllPropertiesByUser(userId);
1✔
299
    libraryCardDAO.deleteAllLibraryCardsByUser(userId);
1✔
300
    acknowledgementDAO.deleteAllAcknowledgementsByUser(userId);
1✔
301
    fileStorageObjectDAO.deleteAllUserFiles(userId);
1✔
302
    userDAO.deleteUserById(userId);
1✔
303
  }
1✔
304

305
  public List<UserProperty> findAllUserProperties(Integer userId) {
306
    return userPropertyDAO.findUserPropertiesByUserIdAndPropertyKeys(userId,
1✔
307
        UserFields.getValues());
1✔
308
  }
309

310
  public void updateEmailPreference(boolean preference, Integer userId) {
311
    userDAO.updateEmailPreference(userId, preference);
×
312
  }
×
313

314
  public List<SimplifiedUser> findSOsByInstitutionId(Integer institutionId) {
315
    if (Objects.isNull(institutionId)) {
1✔
316
      return Collections.emptyList();
1✔
317
    }
318

319
    List<User> users = userDAO.getSOsByInstitution(institutionId);
1✔
320
    return users.stream().map(SimplifiedUser::new).collect(Collectors.toList());
1✔
321
  }
322

323
  public List<User> findUsersByInstitutionId(Integer institutionId) {
324
    if (Objects.isNull(institutionId)) {
1✔
325
      throw new IllegalArgumentException();
1✔
326
    }
327
    Institution institution = institutionDAO.findInstitutionById(institutionId);
1✔
328
    if (Objects.isNull(institution)) {
1✔
329
      throw new NotFoundException();
×
330
    }
331
    return userDAO.findUsersByInstitution(institutionId);
1✔
332
  }
333

334
  public void deleteUserRole(User authUser, Integer userId, Integer roleId) {
335
    userRoleDAO.removeSingleUserRole(userId, roleId);
×
336
    logInfo(
×
337
        "User %s deleted roleId: %s from User ID: %s".formatted(authUser.getDisplayName(), roleId,
×
338
            userId));
339
  }
×
340

341
  public List<User> findUsersWithNoInstitution() {
342
    return userDAO.getUsersWithNoInstitution();
1✔
343
  }
344

345
  /**
346
   * Convenience method to return a response-friendly json object of the user.
347
   *
348
   * @param authUser The AuthUser. Used to determine if we should return auth user properties
349
   * @param userId   The User. This is the user we want to return properties for
350
   * @return JsonObject.
351
   */
352
  public JsonObject findUserWithPropertiesByIdAsJsonObject(AuthUser authUser, Integer userId) {
353
    Gson gson = GsonUtil.getInstance();
1✔
354
    User user = findUserById(userId);
1✔
355
    List<UserProperty> props = findAllUserProperties(user.getUserId());
1✔
356
    List<LibraryCard> entries =
357
        Objects.nonNull(user.getLibraryCards()) ? user.getLibraryCards() : List.of();
1✔
358
    JsonObject userJson = gson.toJsonTree(user).getAsJsonObject();
1✔
359
    JsonArray propsJson = gson.toJsonTree(props).getAsJsonArray();
1✔
360
    JsonArray entriesJson = gson.toJsonTree(entries).getAsJsonArray();
1✔
361
    userJson.add(USER_PROPERTIES_FIELD, propsJson);
1✔
362
    userJson.add(LIBRARY_CARDS_FIELD, entriesJson);
1✔
363
    if (authUser.getEmail().equalsIgnoreCase(user.getEmail()) && Objects.nonNull(
1✔
364
        authUser.getUserStatusInfo())) {
1✔
365
      JsonObject userStatusInfoJson = gson.toJsonTree(authUser.getUserStatusInfo())
1✔
366
          .getAsJsonObject();
1✔
367
      userJson.add(USER_STATUS_INFO_FIELD, userStatusInfoJson);
1✔
368
    }
369
    return userJson;
1✔
370
  }
371

372
  private void validateRequiredFields(User user) {
373
    if (StringUtils.isEmpty(user.getDisplayName())) {
1✔
374
      throw new BadRequestException("Display Name cannot be empty");
1✔
375
    }
376
    if (StringUtils.isEmpty(user.getEmail())) {
1✔
377
      throw new BadRequestException("Email address cannot be empty");
1✔
378
    }
379
    List<String> validRoleNameList = Stream.of(UserRoles.RESEARCHER, UserRoles.ALUMNI,
1✔
380
        UserRoles.ADMIN).map(UserRoles::getRoleName).toList();
1✔
381
    user.getRoles().forEach(role -> {
1✔
382
      if (!validRoleNameList.contains(role.getName())) {
1✔
383
        String validRoleNames = String.join(", ", validRoleNameList);
1✔
384
        throw new BadRequestException(
1✔
385
            "Invalid role: " + role.getName() + ". Valid roles are: " + validRoleNames);
1✔
386
      }
387
    });
1✔
388
  }
1✔
389

390
  public void insertUserRoles(List<UserRole> roles, Integer userId) {
391
    roles.forEach(r -> {
1✔
392
      if (r.getRoleId() == null) {
1✔
393
        r.setRoleId(userRoleDAO.findRoleIdByName(r.getName()));
×
394
      }
395
    });
1✔
396
    userRoleDAO.insertUserRoles(roles, userId);
1✔
397
  }
1✔
398

399
  private Optional<User> getSigningOfficialForUser(Integer userId) {
400
    List<UserProperty> props =
1✔
401
        userPropertyDAO.findUserPropertiesByUserIdAndPropertyKeys(
1✔
402
            userId,
403
            List.of(UserFields.SELECTED_SIGNING_OFFICIAL_ID.getValue())
1✔
404
        );
405

406
    if (props.size() == 0) {
1✔
407
      return Optional.empty();
1✔
408
    }
409

410
    UserProperty soIdProp = props.get(0);
1✔
411

412
    int soId;
413
    try {
414
      soId = Integer.parseInt(soIdProp.getPropertyValue());
1✔
415
    } catch (NumberFormatException e) {
×
416
      return Optional.empty();
×
417
    }
1✔
418

419
    return Optional.ofNullable(userDAO.findUserById(soId));
1✔
420
  }
421

422
  private void addExistingLibraryCards(User user) {
423
    List<LibraryCard> libraryCards = libraryCardDAO.findAllLibraryCardsByUserEmail(user.getEmail());
1✔
424

425
    libraryCards
1✔
426
        .forEach(lc -> {
1✔
427
          libraryCardDAO.updateLibraryCardById(
1✔
428
              lc.getId(),
1✔
429
              user.getUserId(),
1✔
430
              lc.getInstitutionId(),
1✔
431
              lc.getEraCommonsId(),
1✔
432
              lc.getUserName(),
1✔
433
              lc.getUserEmail(),
1✔
434
              user.getUserId(),
1✔
435
              new Date());
436
        });
1✔
437
  }
1✔
438

439
  public User findOrCreateUser(AuthUser authUser) throws Exception {
440
    User user;
441
    // Ensure that the user is a registered DUOS user
442
    try {
443
      user = userDAO.findUserByEmail(authUser.getEmail());
1✔
444
    } catch (NotFoundException nfe) {
1✔
445
      User newUser = new User();
1✔
446
      newUser.setEmail(authUser.getEmail());
1✔
447
      newUser.setDisplayName(authUser.getName());
1✔
448
      user = createUser(newUser);
1✔
449
    }
1✔
450
    // Ensure that the user is a registered SAM user
451
    try {
452
      samDAO.postRegistrationInfo(authUser);
1✔
453
    } catch (ConsentConflictException cce) {
×
454
      // no-op in the case of conflicts.
455
    }
1✔
456
    return user;
1✔
457
  }
458

459
  public List<User> findUsersInJsonArray(String json, String arrayKey) {
460
    List<JsonElement> jsonElementList;
461
    try {
462
      JsonObject jsonObject = new Gson().fromJson(json, JsonObject.class);
1✔
463
      jsonElementList = jsonObject.getAsJsonArray(arrayKey).asList();
1✔
464
    } catch (Exception e) {
1✔
465
      throw new BadRequestException("Invalid JSON or missing array with key: " + arrayKey);
1✔
466
    }
1✔
467
    return jsonElementList.stream().distinct().map(e -> findUserById(e.getAsInt())).toList();
1✔
468
  }
469

470
  public void hasValidActiveERACredentials(Integer userId) {
471
    List<LibraryCard> cards = libraryCardDAO.findLibraryCardsByUserId(userId);
1✔
472
    List<UserProperty> userProperties = findAllUserProperties(userId);
1✔
473
    boolean hasEraCommonsId = cards.stream().anyMatch(c -> c.getEraCommonsId() != null);
1✔
474
    if (!hasEraCommonsId) {
1✔
475
      throw new BadRequestException("User does not have an Era Commons ID");
1✔
476
    }
477
    List<UserProperty> eraStatusProps = userProperties.stream().filter(
1✔
478
            userProperty -> userProperty.getPropertyKey().equalsIgnoreCase(ERA_STATUS.getValue()))
1✔
479
        .toList();
1✔
480
    List<UserProperty> eraExpirationProps = userProperties.stream().filter(
1✔
481
            userProperty -> userProperty.getPropertyKey()
1✔
482
                .equalsIgnoreCase(ERA_EXPIRATION_DATE.getValue()))
1✔
483
        .toList();
1✔
484
    if (eraStatusProps.size() == 1 && eraExpirationProps.size() == 1) {
1✔
485
      if (!eraStatusProps.get(0).getPropertyValue().equalsIgnoreCase("true")) {
1✔
NEW
486
        throw new BadRequestException("User does not have an Era Commons ID that is authorized.");
×
487
      }
488
      if (Long.parseLong(eraExpirationProps.get(0).getPropertyValue()) < System.currentTimeMillis()) {
1✔
489
        throw new BadRequestException("User has an expired Era Commons ID.");
1✔
490
      }
491
    } else {
492
      throw new BadRequestException(
1✔
493
          "Invalid ERA configuration for this user.  Only one ERA Commons ID is allowed.");
494
    }
495
  }
1✔
496

497
  public static class SimplifiedUser {
498

499
    public Integer userId;
500
    public String displayName;
501
    public String email;
502
    public Integer institutionId;
503

504
    public SimplifiedUser(User user) {
1✔
505
      this.userId = user.getUserId();
1✔
506
      this.displayName = user.getDisplayName();
1✔
507
      this.email = user.getEmail();
1✔
508
      this.institutionId = user.getInstitutionId();
1✔
509
    }
1✔
510

511
    public SimplifiedUser() {
1✔
512
    }
1✔
513

514
    public void setUserId(Integer userId) {
515
      this.userId = userId;
1✔
516
    }
1✔
517

518
    public void setDisplayName(String name) {
519
      this.displayName = name;
1✔
520
    }
1✔
521

522
    public void setEmail(String email) {
523
      this.email = email;
1✔
524
    }
1✔
525

526
    public void setInstitutionId(Integer institutionId) {
527
      this.institutionId = institutionId;
×
528
    }
×
529

530
    @Override
531
    public boolean equals(Object o) {
532
      if (this == o) {
1✔
533
        return true;
×
534
      }
535
      if (o == null || getClass() != o.getClass()) {
1✔
536
        return false;
×
537
      }
538
      SimplifiedUser that = (SimplifiedUser) o;
1✔
539
      return Objects.equals(userId, that.userId);
1✔
540
    }
541

542
    @Override
543
    public int hashCode() {
544
      return Objects.hash(userId);
×
545
    }
546
  }
547
}
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