From 1f98f331cef06a12ce6c6385df2bf1db17ba7552 Mon Sep 17 00:00:00 2001 From: Marco Villeneuve Date: Fri, 17 Nov 2023 16:04:29 -0800 Subject: [PATCH] Added endpoint to pull invitations --- .../bc/gov/educ/api/edx/constants/v1/URL.java | 1 + .../edx/controller/v1/EdxUsersController.java | 5 ++++ .../api/edx/endpoint/v1/EdxUsersEndpoint.java | 6 +++++ .../edx/model/v1/EdxActivationCodeEntity.java | 3 +++ .../EdxActivationCodeRepository.java | 4 ++++ .../schedulers/SecureExchangeScheduler.java | 1 - .../api/edx/service/v1/EdxUsersService.java | 20 ++++++++++++---- .../api/edx/struct/v1/EdxActivationCode.java | 2 ++ .../db/migration/V1.0.40__EDX_API.sql | 2 ++ .../controller/EdxUsersControllerTest.java | 24 +++++++++++++++++++ 10 files changed, 62 insertions(+), 6 deletions(-) create mode 100644 api/src/main/resources/db/migration/V1.0.40__EDX_API.sql diff --git a/api/src/main/java/ca/bc/gov/educ/api/edx/constants/v1/URL.java b/api/src/main/java/ca/bc/gov/educ/api/edx/constants/v1/URL.java index 310d2b6c..62732c9b 100644 --- a/api/src/main/java/ca/bc/gov/educ/api/edx/constants/v1/URL.java +++ b/api/src/main/java/ca/bc/gov/educ/api/edx/constants/v1/URL.java @@ -17,6 +17,7 @@ public final class URL { public static final String MINISTRY_TEAMS = "/ministry-teams"; public static final String USER_SCHOOLS = "/user-schools"; public static final String USER_DISTRICTS = "/user-districts"; + public static final String INVITATIONS = "/user-invitations"; private URL(){ diff --git a/api/src/main/java/ca/bc/gov/educ/api/edx/controller/v1/EdxUsersController.java b/api/src/main/java/ca/bc/gov/educ/api/edx/controller/v1/EdxUsersController.java index baec4cef..158b15cb 100644 --- a/api/src/main/java/ca/bc/gov/educ/api/edx/controller/v1/EdxUsersController.java +++ b/api/src/main/java/ca/bc/gov/educ/api/edx/controller/v1/EdxUsersController.java @@ -94,6 +94,11 @@ public EdxUser retrieveEdxUser(String id) { return userMapper.toStructure(getService().retrieveEdxUserByID(UUIDUtil.fromString(id))); } + @Override + public List findAllInvitations(String instituteType) { + return getService().getEdxUserInvitations(instituteType).stream().map(EDX_ACTIVATION_CODE_MAPPER::toStructure).collect(Collectors.toList()); + } + @Override public List findEdxUsers(Optional digitalId, Optional schoolID, String firstName, String lastName, Optional districtID) { return getService().findEdxUsers(digitalId, schoolID, firstName, lastName, districtID).stream().map(userMapper::toStructure).collect(Collectors.toList()); diff --git a/api/src/main/java/ca/bc/gov/educ/api/edx/endpoint/v1/EdxUsersEndpoint.java b/api/src/main/java/ca/bc/gov/educ/api/edx/endpoint/v1/EdxUsersEndpoint.java index 11b033e4..470bebbc 100644 --- a/api/src/main/java/ca/bc/gov/educ/api/edx/endpoint/v1/EdxUsersEndpoint.java +++ b/api/src/main/java/ca/bc/gov/educ/api/edx/endpoint/v1/EdxUsersEndpoint.java @@ -68,6 +68,12 @@ public interface EdxUsersEndpoint { EdxUser retrieveEdxUser(@PathVariable String id); + @PreAuthorize("hasAuthority('SCOPE_READ_EDX_USERS')") + @GetMapping(URL.INVITATIONS) + @Transactional(readOnly = true) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK")}) + List findAllInvitations(@RequestParam(name = "instituteType") String instituteType); + /** * This api method will accept all or individual parameters and search the DB. if any parameter is null then it will be not included in the query. * diff --git a/api/src/main/java/ca/bc/gov/educ/api/edx/model/v1/EdxActivationCodeEntity.java b/api/src/main/java/ca/bc/gov/educ/api/edx/model/v1/EdxActivationCodeEntity.java index cbcda791..83ab588d 100644 --- a/api/src/main/java/ca/bc/gov/educ/api/edx/model/v1/EdxActivationCodeEntity.java +++ b/api/src/main/java/ca/bc/gov/educ/api/edx/model/v1/EdxActivationCodeEntity.java @@ -42,6 +42,9 @@ public class EdxActivationCodeEntity { @Column(name = "EDX_USER_ID") UUID edxUserId; + @Column(name = "LINKED_EDX_USER_ID") + UUID linkedEdxUserId; + @NotNull(message = "isPrimary cannot be null") @Column(name = "IS_PRIMARY") Boolean isPrimary; diff --git a/api/src/main/java/ca/bc/gov/educ/api/edx/repository/EdxActivationCodeRepository.java b/api/src/main/java/ca/bc/gov/educ/api/edx/repository/EdxActivationCodeRepository.java index f75ba4da..823c3a07 100644 --- a/api/src/main/java/ca/bc/gov/educ/api/edx/repository/EdxActivationCodeRepository.java +++ b/api/src/main/java/ca/bc/gov/educ/api/edx/repository/EdxActivationCodeRepository.java @@ -22,4 +22,8 @@ public interface EdxActivationCodeRepository extends JpaRepository findEdxActivationCodeEntitiesByDistrictIDAndIsPrimaryTrueAndSchoolIDIsNull(UUID districtID); List findEdxActivationCodeEntitiesByEdxUserId(UUID edxUserId); + + List findAllByDistrictIDIsNotNullAndIsPrimaryIsFalse(); + + List findAllBySchoolIDIsNotNullAndIsPrimaryIsFalse(); } diff --git a/api/src/main/java/ca/bc/gov/educ/api/edx/schedulers/SecureExchangeScheduler.java b/api/src/main/java/ca/bc/gov/educ/api/edx/schedulers/SecureExchangeScheduler.java index 5afd5389..783f119b 100644 --- a/api/src/main/java/ca/bc/gov/educ/api/edx/schedulers/SecureExchangeScheduler.java +++ b/api/src/main/java/ca/bc/gov/educ/api/edx/schedulers/SecureExchangeScheduler.java @@ -87,7 +87,6 @@ public void purgeClosedMessages() { documentRepository.deleteByCreateDateBefore(createDate); secureExchangeRepository.deleteByCreateDateBefore(createDate); log.info("Purged closed messages scheduler"); - } private LocalDateTime calculateCreateDateBasedOnMessageAge() { diff --git a/api/src/main/java/ca/bc/gov/educ/api/edx/service/v1/EdxUsersService.java b/api/src/main/java/ca/bc/gov/educ/api/edx/service/v1/EdxUsersService.java index 3b27df07..51239760 100644 --- a/api/src/main/java/ca/bc/gov/educ/api/edx/service/v1/EdxUsersService.java +++ b/api/src/main/java/ca/bc/gov/educ/api/edx/service/v1/EdxUsersService.java @@ -120,6 +120,15 @@ public List getEdxUserSchoolsList(String permissionCode) { return schoolIDBytes.stream().map(school -> school.getSchoolID().toString()).distinct().toList(); } + public List getEdxUserInvitations(String instituteType) { + if(instituteType.equalsIgnoreCase(InstituteTypeCode.DISTRICT.toString())){ + return edxActivationCodeRepository.findAllByDistrictIDIsNotNullAndIsPrimaryIsFalse(); + }else if(instituteType.equalsIgnoreCase(InstituteTypeCode.SCHOOL.toString())){ + return edxActivationCodeRepository.findAllBySchoolIDIsNotNullAndIsPrimaryIsFalse(); + } + return edxActivationCodeRepository.findAll(); + } + public List getEdxUserDistrictsList(String permissionCode) { List districtIDs = edxUserDistrictRepository.findDistrictsByPermission(permissionCode); return districtIDs.stream().map(district -> district.getDistrictID().toString()).distinct().toList(); @@ -503,8 +512,8 @@ private EdxUserEntity updateEdxUserDetailsFromActivationCodeDetails(List new EntityNotFoundException(EdxActivationCodeEntity.class, EDX_ACTIVATION_CODE_ID, edxActivationCode.getEdxActivationCodeId().toString())); if (!activationCodeEntity.getIsPrimary()) {//expire only the personal activation code activationCodeEntity.setExpiryDate(LocalDateTime.now()); + activationCodeEntity.setLinkedEdxUserId(user.getEdxUserID()); activationCodeEntity.setUpdateUser(edxActivateUser.getUpdateUser()); activationCodeEntity.setUpdateDate(LocalDateTime.now()); getEdxActivationCodeRepository().save(activationCodeEntity); diff --git a/api/src/main/java/ca/bc/gov/educ/api/edx/struct/v1/EdxActivationCode.java b/api/src/main/java/ca/bc/gov/educ/api/edx/struct/v1/EdxActivationCode.java index ecfbdb4b..dc404787 100644 --- a/api/src/main/java/ca/bc/gov/educ/api/edx/struct/v1/EdxActivationCode.java +++ b/api/src/main/java/ca/bc/gov/educ/api/edx/struct/v1/EdxActivationCode.java @@ -51,5 +51,7 @@ public class EdxActivationCode extends BaseRequest implements Serializable { String edxUserId; + String linkedEdxUserId; + String edxUserExpiryDate; } diff --git a/api/src/main/resources/db/migration/V1.0.40__EDX_API.sql b/api/src/main/resources/db/migration/V1.0.40__EDX_API.sql new file mode 100644 index 00000000..f9d268a4 --- /dev/null +++ b/api/src/main/resources/db/migration/V1.0.40__EDX_API.sql @@ -0,0 +1,2 @@ +ALTER TABLE EDX_ACTIVATION_CODE ADD COLUMN LINKED_EDX_USER_ID UUID; + diff --git a/api/src/test/java/ca/bc/gov/educ/api/edx/controller/EdxUsersControllerTest.java b/api/src/test/java/ca/bc/gov/educ/api/edx/controller/EdxUsersControllerTest.java index 5b6dd046..400ee68c 100644 --- a/api/src/test/java/ca/bc/gov/educ/api/edx/controller/EdxUsersControllerTest.java +++ b/api/src/test/java/ca/bc/gov/educ/api/edx/controller/EdxUsersControllerTest.java @@ -87,6 +87,30 @@ void testRetrieveMinistryTeams_ShouldReturnOkStatus() throws Exception { .andExpect(jsonPath("$.[0].description", is("THISISDESCRIPTION"))); } + @Test + void testFindAllSchoolInvitations_ShouldReturnOkStatus() throws Exception { + UUID validationCode = UUID.randomUUID(); + UUID schoolID = UUID.randomUUID(); + this.createActivationCodeTableDataForSchoolUser(this.edxActivationCodeRepository, this.edxPermissionRepository, this.edxRoleRepository, this.edxActivationRoleRepository, true,validationCode, 2, schoolID); + this.mockMvc.perform(get(URL.BASE_URL_USERS + URL.INVITATIONS + "?instituteType=SCHOOL") + .with(jwt().jwt((jwt) -> jwt.claim("scope", "READ_EDX_USERS")))) + .andDo(print()).andExpect(status().isOk()) + .andExpect(jsonPath("$", hasSize(1))); + } + + @Test + void testFindAllDistrictInvitations_ShouldReturnOkStatus() throws Exception { + UUID validationCode = UUID.randomUUID(); + UUID districtID = UUID.randomUUID(); + this.createActivationCodeTableDataForDistrictUser(this.edxActivationCodeRepository, this.edxPermissionRepository, this.edxRoleRepository, this.edxActivationRoleRepository, true,validationCode, 2, districtID); + UUID districtID2 = UUID.randomUUID(); + this.createActivationCodeTableDataForDistrictUser(this.edxActivationCodeRepository, this.edxPermissionRepository, this.edxRoleRepository, this.edxActivationRoleRepository, true,validationCode, 2, districtID2); + this.mockMvc.perform(get(URL.BASE_URL_USERS + URL.INVITATIONS + "?instituteType=DISTRICT") + .with(jwt().jwt((jwt) -> jwt.claim("scope", "READ_EDX_USERS")))) + .andDo(print()).andExpect(status().isOk()) + .andExpect(jsonPath("$", hasSize(2))); + } + @Test void testRetrieveUsers_GivenValidID_ShouldReturnOkStatus() throws Exception { var entity = this.createUserEntity(this.edxUserRepository, this.edxPermissionRepository, this.edxRoleRepository, this.edxUserSchoolRepository, this.edxUserDistrictRepository);