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

DataBiosphere / consent / #6031

06 Jun 2025 06:06PM CUT coverage: 78.949% (+0.01%) from 78.938%
#6031

push

web-flow
DT-1659, DT-1675: Filter approved users to those with library cards (#2553)

16 of 16 new or added lines in 3 files covered. (100.0%)

1 existing line in 1 file now uncovered.

10137 of 12840 relevant lines covered (78.95%)

0.79 hits per line

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

89.86
/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.common.annotations.VisibleForTesting;
7
import com.google.gson.Gson;
8
import com.google.gson.JsonArray;
9
import com.google.gson.JsonElement;
10
import com.google.gson.JsonObject;
11
import com.google.inject.Inject;
12
import jakarta.ws.rs.BadRequestException;
13
import jakarta.ws.rs.NotFoundException;
14
import java.time.Instant;
15
import java.util.Collections;
16
import java.util.Date;
17
import java.util.List;
18
import java.util.Objects;
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.exceptions.LibraryCardRequiredException;
36
import org.broadinstitute.consent.http.models.AuthUser;
37
import org.broadinstitute.consent.http.models.DataAccessAgreement;
38
import org.broadinstitute.consent.http.models.Institution;
39
import org.broadinstitute.consent.http.models.LibraryCard;
40
import org.broadinstitute.consent.http.models.User;
41
import org.broadinstitute.consent.http.models.UserProperty;
42
import org.broadinstitute.consent.http.models.UserRole;
43
import org.broadinstitute.consent.http.models.UserUpdateFields;
44
import org.broadinstitute.consent.http.models.Vote;
45
import org.broadinstitute.consent.http.resources.Resource;
46
import org.broadinstitute.consent.http.service.dao.DraftServiceDAO;
47
import org.broadinstitute.consent.http.service.dao.UserServiceDAO;
48
import org.broadinstitute.consent.http.util.ConsentLogger;
49
import org.broadinstitute.consent.http.util.gson.GsonUtil;
50

51
public class UserService implements ConsentLogger {
52

53
  public static final String LIBRARY_CARD_FIELD = "libraryCard";
54
  public static final String LIBRARY_CARDS_FIELD = "libraryCards";
55
  public static final String USER_PROPERTIES_FIELD = "properties";
56
  public static final String USER_STATUS_INFO_FIELD = "userStatusInfo";
57

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

72
  @Inject
73
  public UserService(UserDAO userDAO, UserPropertyDAO userPropertyDAO, UserRoleDAO userRoleDAO,
74
      VoteDAO voteDAO, InstitutionDAO institutionDAO, LibraryCardDAO libraryCardDAO,
75
      AcknowledgementDAO acknowledgementDAO, FileStorageObjectDAO fileStorageObjectDAO,
76
      SamDAO samDAO, UserServiceDAO userServiceDAO, DaaDAO daaDAO, DraftServiceDAO draftServiceDAO,
77
      InstitutionService institutionService) {
1✔
78
    this.userDAO = userDAO;
1✔
79
    this.userPropertyDAO = userPropertyDAO;
1✔
80
    this.userRoleDAO = userRoleDAO;
1✔
81
    this.voteDAO = voteDAO;
1✔
82
    this.institutionDAO = institutionDAO;
1✔
83
    this.libraryCardDAO = libraryCardDAO;
1✔
84
    this.acknowledgementDAO = acknowledgementDAO;
1✔
85
    this.fileStorageObjectDAO = fileStorageObjectDAO;
1✔
86
    this.samDAO = samDAO;
1✔
87
    this.userServiceDAO = userServiceDAO;
1✔
88
    this.daaDAO = daaDAO;
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
      // Update User Properties
117
      List<UserProperty> userProps = userUpdateFields.buildUserProperties(userId);
1✔
118
      if (!userProps.isEmpty()) {
1✔
119
        userPropertyDAO.deletePropertiesByUserAndKey(userProps);
1✔
120
        userPropertyDAO.insertAll(userProps);
1✔
121
      }
122

123
      // Handle Roles
124
      if (Objects.nonNull(userUpdateFields.getUserRoleIds())) {
1✔
125
        List<Integer> currentRoleIds = userRoleDAO.findRolesByUserId(userId).stream()
1✔
126
            .map(UserRole::getRoleId).toList();
1✔
127
        List<Integer> roleIdsToAdd = userUpdateFields.getRoleIdsToAdd(currentRoleIds);
1✔
128
        List<Integer> roleIdsToRemove = userUpdateFields.getRoleIdsToRemove(currentRoleIds);
1✔
129
        // Add the new role ids to the user
130
        if (!roleIdsToAdd.isEmpty()) {
1✔
131
          List<UserRole> newRoles = roleIdsToAdd.stream()
1✔
132
              .map(id -> new UserRole(id,
1✔
133
                  Objects.requireNonNull(UserRoles.getUserRoleFromId(id)).getRoleName()))
1✔
134
              .toList();
1✔
135
          userRoleDAO.insertUserRoles(newRoles, userId);
1✔
136
        }
137
        // Remove the old role ids from the user
138
        if (!roleIdsToRemove.isEmpty()) {
1✔
139
          userRoleDAO.removeUserRoles(userId, roleIdsToRemove);
1✔
140
        }
141
      }
142

143
    }
144
    return findUserById(userId);
1✔
145
  }
146

147
  public void insertRoleAndInstitutionForUser(UserRole role, User user) {
148
    var userId = user.getUserId();
1✔
149
    try {
150
      if (user.getInstitutionId() == null) {
1✔
151
        Institution institution = institutionService.findInstitutionForEmail(user.getEmail());
1✔
152
        if (institution == null) {
1✔
153
          throw new BadRequestException(
1✔
154
              "No institution found for user: %s".formatted(user.getEmail()));
1✔
155
        }
156
        userServiceDAO.insertRoleAndInstitutionTxn(role, institution.getId(), userId);
1✔
157
      } else {
1✔
158
        userRoleDAO.insertSingleUserRole(role.getRoleId(), userId);
1✔
159
      }
160
    } catch (Exception e) {
1✔
161
      logException(
1✔
162
          "Error when updating user: %s, role: %s".formatted(userId, role), e);
1✔
163
      throw e;
1✔
164
    }
1✔
165
  }
1✔
166

167
  public User createUser(User user) {
168
    // Default role is researcher.
169
    if (CollectionUtils.isEmpty(user.getRoles())) {
1✔
170
      user.setResearcherRole();
1✔
171
    }
172
    validateRequiredFields(user);
1✔
173
    User existingUser = userDAO.findUserByEmail(user.getEmail());
1✔
174
    if (Objects.nonNull(existingUser)) {
1✔
175
      throw new BadRequestException("User exists with this email address: " + user.getEmail());
1✔
176
    }
177
    Institution institution = institutionService.findInstitutionForEmail(user.getEmail());
1✔
178
    if (institution != null) {
1✔
179
      user.setInstitutionId(institution.getId());
1✔
180
    }
181
    Integer userId = userDAO.insertUser(user.getEmail(), user.getDisplayName(),
1✔
182
        user.getInstitutionId(), new Date());
1✔
183
    insertUserRoles(user.getRoles(), userId);
1✔
184
    assignExistingLibraryCardToUser(user);
1✔
185
    return userDAO.findUserById(userId);
1✔
186
  }
187

188
  public User findUserById(Integer id) throws NotFoundException {
189
    User user = userDAO.findUserById(id);
1✔
190
    if (user == null) {
1✔
191
      throw new NotFoundException("Unable to find user with id: " + id);
1✔
192
    }
193
    return user;
1✔
194
  }
195

196
  public User findUserByEmail(String email) throws NotFoundException {
197
    User user = userDAO.findUserByEmail(email);
1✔
198
    if (user == null) {
1✔
199
      throw new NotFoundException("Unable to find user with email: " + email);
1✔
200
    }
201
    return user;
1✔
202
  }
203

204
  /**
205
   * Find users as a specific role, e.g., Admins can see all users, other roles can only see a
206
   * subset of users.
207
   *
208
   * @param user     The user making the request
209
   * @param roleName The role the user is making the request as
210
   * @return List of Users for specified role name
211
   */
212
  public List<User> getUsersAsRole(User user, String roleName) {
213
    switch (roleName) {
1✔
214
      // SigningOfficial console is technically pulling LCs, it's just bringing associated users along for the ride
215
      // However LCs can be created for users not yet registered in the system
216
      // As such a more specialized query is needed to produce the proper listing
217
      case Resource.SIGNINGOFFICIAL:
218
        Integer institutionId = user.getInstitutionId();
1✔
219
        if (Objects.nonNull(user.getInstitutionId())) {
1✔
220
          return userDAO.getUsersFromInstitutionWithCards(institutionId);
1✔
221
        } else {
222
          throw new NotFoundException("Signing Official (user: " + user.getDisplayName()
1✔
223
              + ") is not associated with an Institution.");
224
        }
225
      case Resource.ADMIN:
226
        return userDAO.findUsersWithLCsAndInstitution();
1✔
227
      default:
228
        // do nothing
229
    }
230
    return Collections.emptyList();
×
231
  }
232

233
  public List<SimplifiedUser> getUsersByDaaId(Integer daaId) {
234
    if (Objects.isNull(daaId)) {
1✔
235
      throw new IllegalArgumentException();
×
236
    }
237
    DataAccessAgreement daa = daaDAO.findById(daaId);
1✔
238
    if (Objects.isNull(daa)) {
1✔
239
      throw new NotFoundException();
1✔
240
    }
241
    List<User> users = userDAO.getUsersWithCardsByDaaId(daaId);
1✔
242
    return users.stream().map(SimplifiedUser::new).toList();
1✔
243
  }
244

245
  public void deleteUserByEmail(String email) {
246
    User user = userDAO.findUserByEmail(email);
1✔
247
    if (user == null) {
1✔
248
      throw new NotFoundException("The user for the specified E-Mail address does not exist");
×
249
    }
250
    Integer userId = user.getUserId();
1✔
251
    List<Integer> roleIds = userRoleDAO.
1✔
252
        findRolesByUserId(userId).
1✔
253
        stream().
1✔
254
        map(UserRole::getRoleId).
1✔
255
        toList();
1✔
256
    if (!roleIds.isEmpty()) {
1✔
257
      userRoleDAO.removeUserRoles(userId, roleIds);
×
258
    }
259
    List<Vote> votes = voteDAO.findVotesByUserId(userId);
1✔
260
    if (!votes.isEmpty()) {
1✔
261
      List<Integer> voteIds = votes.stream().map(Vote::getVoteId).toList();
×
262
      voteDAO.removeVotesByIds(voteIds);
×
263
    }
264
    try {
265
      draftServiceDAO.deleteDraftsByUser(user);
1✔
266
    } catch (Exception e) {
×
267
      logException(
×
268
          String.format("Unable to delete all drafts and files for userId %d. Error was: %s",
×
269
              userId, e.getMessage()), e);
×
270
    }
1✔
271
    institutionDAO.deleteAllInstitutionsByUser(userId);
1✔
272
    userPropertyDAO.deleteAllPropertiesByUser(userId);
1✔
273
    libraryCardDAO.deleteAllLibraryCardsByUser(userId);
1✔
274
    acknowledgementDAO.deleteAllAcknowledgementsByUser(userId);
1✔
275
    fileStorageObjectDAO.deleteAllUserFiles(userId);
1✔
276
    userDAO.deleteUserById(userId);
1✔
277
  }
1✔
278

279
  public List<UserProperty> findAllUserProperties(Integer userId) {
280
    return userPropertyDAO.findUserPropertiesByUserIdAndPropertyKeys(userId,
1✔
281
        UserFields.getValues());
1✔
282
  }
283

284
  public void updateEmailPreference(boolean preference, Integer userId) {
285
    userDAO.updateEmailPreference(userId, preference);
×
286
  }
×
287

288
  public List<SimplifiedUser> findSOsByInstitutionId(Integer institutionId) {
289
    if (Objects.isNull(institutionId)) {
1✔
290
      return Collections.emptyList();
1✔
291
    }
292

293
    List<User> users = userDAO.getSOsByInstitution(institutionId);
1✔
294
    return users.stream().map(SimplifiedUser::new).toList();
1✔
295
  }
296

297
  public List<User> findUsersByInstitutionId(Integer institutionId) {
298
    if (Objects.isNull(institutionId)) {
1✔
299
      throw new IllegalArgumentException();
1✔
300
    }
301
    Institution institution = institutionDAO.findInstitutionById(institutionId);
1✔
302
    if (Objects.isNull(institution)) {
1✔
303
      throw new NotFoundException();
×
304
    }
305
    return userDAO.findUsersByInstitution(institutionId);
1✔
306
  }
307

308
  public void deleteUserRole(User authUser, Integer userId, Integer roleId) {
309
    userRoleDAO.removeSingleUserRole(userId, roleId);
×
310
    logInfo(
×
311
        "User %s deleted roleId: %s from User ID: %s".formatted(authUser.getDisplayName(), roleId,
×
312
            userId));
313
  }
×
314

315
  public List<User> findUsersWithNoInstitution() {
316
    return userDAO.getUsersWithNoInstitution();
1✔
317
  }
318

319
  /**
320
   * Convenience method to return a response-friendly json object of the user.
321
   *
322
   * @param authUser The AuthUser. Used to determine if we should return auth user properties
323
   * @param userId   The User. This is the user we want to return properties for
324
   * @return JsonObject.
325
   */
326
  public JsonObject findUserWithPropertiesByIdAsJsonObject(AuthUser authUser, Integer userId) {
327
    Gson gson = GsonUtil.getInstance();
1✔
328
    User user = findUserById(userId);
1✔
329
    List<UserProperty> props = findAllUserProperties(user.getUserId());
1✔
330
    JsonObject userJson = gson.toJsonTree(user).getAsJsonObject();
1✔
331
    JsonArray propsJson = gson.toJsonTree(props).getAsJsonArray();
1✔
332
    userJson.add(USER_PROPERTIES_FIELD, propsJson);
1✔
333
    if (user.getLibraryCard() != null) {
1✔
334
      JsonObject libraryCardJson = gson.toJsonTree(user.getLibraryCard()).getAsJsonObject();
1✔
335
      userJson.add(LIBRARY_CARD_FIELD, libraryCardJson);
1✔
336
      // Note that this is provided for backwards compatibility with the UI and will be removed
337
      userJson.add(LIBRARY_CARDS_FIELD, gson.toJsonTree(List.of(libraryCardJson)));
1✔
338
    }
339
    if (authUser.getEmail().equalsIgnoreCase(user.getEmail()) && Objects.nonNull(
1✔
340
        authUser.getUserStatusInfo())) {
1✔
341
      JsonObject userStatusInfoJson = gson.toJsonTree(authUser.getUserStatusInfo())
1✔
342
          .getAsJsonObject();
1✔
343
      userJson.add(USER_STATUS_INFO_FIELD, userStatusInfoJson);
1✔
344
    }
345
    return userJson;
1✔
346
  }
347

348
  private void validateRequiredFields(User user) {
349
    if (StringUtils.isEmpty(user.getDisplayName())) {
1✔
350
      throw new BadRequestException("Display Name cannot be empty");
1✔
351
    }
352
    if (StringUtils.isEmpty(user.getEmail())) {
1✔
353
      throw new BadRequestException("Email address cannot be empty");
1✔
354
    }
355
    List<String> validRoleNameList = Stream.of(UserRoles.RESEARCHER, UserRoles.ALUMNI,
1✔
356
        UserRoles.ADMIN).map(UserRoles::getRoleName).toList();
1✔
357
    user.getRoles().forEach(role -> {
1✔
358
      if (!validRoleNameList.contains(role.getName())) {
1✔
359
        String validRoleNames = String.join(", ", validRoleNameList);
1✔
360
        throw new BadRequestException(
1✔
361
            "Invalid role: " + role.getName() + ". Valid roles are: " + validRoleNames);
1✔
362
      }
363
    });
1✔
364
  }
1✔
365

366
  public void insertUserRoles(List<UserRole> roles, Integer userId) {
367
    roles.forEach(r -> {
1✔
368
      if (r.getRoleId() == null) {
1✔
369
        r.setRoleId(userRoleDAO.findRoleIdByName(r.getName()));
×
370
      }
371
    });
1✔
372
    userRoleDAO.insertUserRoles(roles, userId);
1✔
373
  }
1✔
374

375
  private void assignExistingLibraryCardToUser(User user) {
376
    LibraryCard libraryCard = libraryCardDAO.findLibraryCardByUserEmail(user.getEmail());
1✔
377
    if (libraryCard != null) {
1✔
378
      libraryCardDAO.updateLibraryCardById(
1✔
379
          libraryCard.getId(),
1✔
380
          user.getUserId(),
1✔
381
          user.getDisplayName(),
1✔
382
          user.getEmail(),
1✔
383
          user.getUserId(),
1✔
384
          new Date());
385
    }
386
  }
1✔
387

388
  public User findOrCreateUser(AuthUser authUser) throws Exception {
389
    User user;
390
    // Ensure that the user is a registered DUOS user
391
    try {
392
      user = userDAO.findUserByEmail(authUser.getEmail());
1✔
393
    } catch (NotFoundException nfe) {
1✔
394
      User newUser = new User();
1✔
395
      newUser.setEmail(authUser.getEmail());
1✔
396
      newUser.setDisplayName(authUser.getName());
1✔
397
      user = createUser(newUser);
1✔
398
    }
1✔
399
    // Ensure that the user is a registered SAM user
400
    try {
401
      samDAO.postRegistrationInfo(authUser);
1✔
402
    } catch (ConsentConflictException cce) {
×
403
      // no-op in the case of conflicts.
404
    }
1✔
405
    return user;
1✔
406
  }
407

408
  public List<User> findUsersInJsonArray(String json, String arrayKey) {
409
    List<JsonElement> jsonElementList;
410
    try {
411
      JsonObject jsonObject = new Gson().fromJson(json, JsonObject.class);
1✔
412
      jsonElementList = jsonObject.getAsJsonArray(arrayKey).asList();
1✔
413
    } catch (Exception e) {
1✔
414
      throw new BadRequestException("Invalid JSON or missing array with key: " + arrayKey);
1✔
415
    }
1✔
416
    return jsonElementList.stream().distinct().map(e -> findUserById(e.getAsInt())).toList();
1✔
417
  }
418

419
  public void validateActiveERACredentials(User user) {
420
    if (user.getLibraryCard() == null) {
1✔
421
      throw new LibraryCardRequiredException();
1✔
422
    }
423
    boolean hasEraCommonsId = user.getEraCommonsId() != null;
1✔
424
    if (!hasEraCommonsId) {
1✔
425
      throw new BadRequestException("User does not have an Era Commons ID");
1✔
426
    }
427
    List<UserProperty> userProperties = findAllUserProperties(user.getUserId());
1✔
428
    List<UserProperty> eraStatusProps = userProperties.stream().filter(
1✔
429
            userProperty -> userProperty.getPropertyKey().equalsIgnoreCase(ERA_STATUS.getValue()))
1✔
430
        .toList();
1✔
431
    List<UserProperty> eraExpirationProps = userProperties.stream().filter(
1✔
432
            userProperty -> userProperty.getPropertyKey()
1✔
433
                .equalsIgnoreCase(ERA_EXPIRATION_DATE.getValue()))
1✔
434
        .toList();
1✔
435
    if (eraStatusProps.size() == 1 && eraExpirationProps.size() == 1) {
1✔
436
      if (!eraStatusProps.get(0).getPropertyValue().equalsIgnoreCase("true")) {
1✔
437
        throw new BadRequestException("User does not have an Era Commons ID that is authorized.");
×
438
      }
439
      if (Instant.ofEpochMilli(Long.parseLong(eraExpirationProps.get(0).getPropertyValue()))
1✔
440
          .isBefore(Instant.now())) {
1✔
441
        throw new BadRequestException("User has an expired Era Commons ID.");
1✔
442
      }
443
    } else {
444
      throw new BadRequestException(
1✔
445
          "Invalid ERA configuration for this user.  Only one ERA Commons ID is allowed.");
446
    }
447
  }
1✔
448

449
  /**
450
   * Compliance method that implements a set of rules in order to ensure Library Card and
451
   * Institution matching rules are adhered to when authorizing users of the system.
452
   * @param email of the user being evaluated
453
   * @return user with the Institution and Library Card rules applied or null if the requestor isn't
454
   * a DUOS user.
455
   */
456
  public User enforceInstitutionAndLibraryCardRules(String email) {
457
    User user;
458
    Institution institutionFromEmail = institutionService.findInstitutionForEmail(email);
1✔
459
    try {
460
      user = findUserByEmail(email);
1✔
461
    } catch (NotFoundException nfe) {
×
462
      return null;
×
463
    }
1✔
464

465
    boolean modifiedUser = false;
1✔
466

467
    if (institutionFromEmail != null) {
1✔
468
      if (handleUserWithInstitutionInMap(user, institutionFromEmail)) {
1✔
469
        modifiedUser = true;
1✔
470
      }
471
    } else {
472
      if (handleUserWithoutInstitutionInMap(user)) {
1✔
473
        modifiedUser = true;
1✔
474
      }
475
    }
476

477
    if (modifiedUser) {
1✔
478
      return findUserByEmail(user.getEmail());
1✔
479
    } else {
UNCOV
480
      return user;
×
481
    }
482
  }
483

484
  @VisibleForTesting
485
  protected boolean handleUserWithInstitutionInMap(User user, Institution institutionFromEmail) {
486
    boolean needsLCRemoved = needsLibraryCardRemovedForUser(user, institutionFromEmail);
1✔
487
    boolean needsInstitutionAssigned = !institutionFromEmail.getId()
1✔
488
        .equals(user.getInstitutionId());
1✔
489

490
    if (needsInstitutionAssigned && needsLCRemoved) {
1✔
491
      userServiceDAO.updateInstitutionAndClearLibraryCardForUser(user.getUserId(), institutionFromEmail.getId());
1✔
492
    } else if (needsInstitutionAssigned) {
1✔
493
      userDAO.updateInstitutionId(user.getUserId(), institutionFromEmail.getId());
1✔
494
    } else if (needsLCRemoved) {
1✔
495
      libraryCardDAO.deleteAllLibraryCardsByUser(user.getUserId());
1✔
496
    }
497

498
    return needsLCRemoved || needsInstitutionAssigned;
1✔
499
  }
500

501
  @VisibleForTesting
502
  protected boolean needsLibraryCardRemovedForUser(User user, Institution userInstitution) {
503
    boolean needsLCRemoved = false;
1✔
504
    if (hasLibraryCard(user)) {
1✔
505
      try {
506
        User lcIssuer = findUserById(user.getLibraryCard().getCreateUserId());
1✔
507
        Institution lcIssuerInstitution = institutionService.findInstitutionForEmail(lcIssuer.getEmail());
1✔
508
        if (!userInstitution.equals(lcIssuerInstitution)) {
1✔
509
          needsLCRemoved = true;
1✔
510
        }
511
      } catch (NotFoundException nfe) {
1✔
512
        needsLCRemoved = true;
1✔
513
      }
1✔
514
    }
515
    return needsLCRemoved;
1✔
516
  }
517

518
  @VisibleForTesting
519
  protected boolean handleUserWithoutInstitutionInMap(User user) {
520
    if (hasLibraryCard(user)) {
1✔
521
      dropLCAndInstitutionForUser(user);
1✔
522
      return true;
1✔
523
    } else {
524
      if (user.getInstitutionId() != null) {
1✔
525
        userDAO.updateInstitutionId(user.getUserId(), null);
1✔
526
        return true;
1✔
527
      }
528
    }
529
    return false;
×
530
  }
531

532
  private void dropLCAndInstitutionForUser(User user) {
533
    userServiceDAO.updateInstitutionAndClearLibraryCardForUser(user.getUserId(), null);
1✔
534
  }
1✔
535

536
  @VisibleForTesting
537
  protected boolean hasLibraryCard(User user) {
538
    return user.getLibraryCard() != null;
1✔
539
  }
540

541
  @VisibleForTesting
542
  protected boolean hasMatchingInstitutionInDatabase(
543
      Institution institutionFromEmail, Institution institutionFromDatabase) {
544
    if (institutionFromEmail == null || institutionFromDatabase == null) {
1✔
545
      return false;
1✔
546
    }
547
    return institutionFromDatabase.equals(institutionFromEmail);
1✔
548
  }
549

550
  public static class SimplifiedUser {
551

552
    private Integer userId;
553
    private String displayName;
554
    private String email;
555
    private Integer institutionId;
556

557
    public SimplifiedUser(User user) {
1✔
558
      this.userId = user.getUserId();
1✔
559
      this.displayName = user.getDisplayName();
1✔
560
      this.email = user.getEmail();
1✔
561
      this.institutionId = user.getInstitutionId();
1✔
562
    }
1✔
563

564
    public SimplifiedUser() {
1✔
565
    }
1✔
566

567
    public void setUserId(Integer userId) {
568
      this.userId = userId;
1✔
569
    }
1✔
570

571
    public void setDisplayName(String name) {
572
      this.displayName = name;
1✔
573
    }
1✔
574

575
    public void setEmail(String email) {
576
      this.email = email;
1✔
577
    }
1✔
578

579
    public void setInstitutionId(Integer institutionId) {
580
      this.institutionId = institutionId;
×
581
    }
×
582

583
    public String getDisplayName() {
584
      return displayName;
1✔
585
    }
586

587
    public String getEmail() {
588
      return email;
1✔
589
    }
590

591
    public Integer getInstitutionId() {
592
      return institutionId;
×
593
    }
594

595
    public Integer getUserId() {
596
      return userId;
1✔
597
    }
598

599
    @Override
600
    public boolean equals(Object o) {
601
      if (this == o) {
1✔
602
        return true;
×
603
      }
604
      if (o == null || getClass() != o.getClass()) {
1✔
605
        return false;
×
606
      }
607
      SimplifiedUser that = (SimplifiedUser) o;
1✔
608
      return Objects.equals(userId, that.userId);
1✔
609
    }
610

611
    @Override
612
    public int hashCode() {
613
      return Objects.hash(userId);
×
614
    }
615
  }
616
}
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