From 20771cb0e244d99183113efd055a2582ed49e5ff Mon Sep 17 00:00:00 2001 From: junaidiqbalmoj Date: Mon, 25 Nov 2024 17:04:52 +0000 Subject: [PATCH 1/6] View Audit Logs --- .../management/controllers/AuditTest.java | 4 ++- .../controllers/AuditController.java | 18 ++++++++-- .../management/database/AuditRepository.java | 10 +++++- .../management/service/AuditService.java | 35 +++++++++++++++++-- .../controllers/AuditControllerTest.java | 12 +++++-- .../management/service/AuditServiceTest.java | 15 ++++++-- 6 files changed, 83 insertions(+), 11 deletions(-) diff --git a/src/integrationTest/java/uk/gov/hmcts/reform/pip/account/management/controllers/AuditTest.java b/src/integrationTest/java/uk/gov/hmcts/reform/pip/account/management/controllers/AuditTest.java index eae6f2537..426d9dc9e 100644 --- a/src/integrationTest/java/uk/gov/hmcts/reform/pip/account/management/controllers/AuditTest.java +++ b/src/integrationTest/java/uk/gov/hmcts/reform/pip/account/management/controllers/AuditTest.java @@ -52,6 +52,8 @@ class AuditTest { private static final String UNAUTHORIZED_USERNAME = "unauthorized_isAuthorized"; private static final String FORBIDDEN_STATUS_CODE = "Status code does not match forbidden"; private static final String GET_AUDIT_LOG_FAILED = "Failed to retrieve audit log"; + private static final String GET_ALL_AUDIT_PARAMS = + "?filterStartDate=2020-01-01T00:00:00.000Z&filterEndDate=2100-01-01T00:00:00.000Z"; private static final AuditAction AUDIT_ACTION = AuditAction.MANAGE_THIRD_PARTY_USER_VIEW; private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); @@ -94,7 +96,7 @@ void testGetAllAuditLogs() throws Exception { .contentType(MediaType.APPLICATION_JSON); mockMvc.perform(mockHttpServletRequestBuilder2).andExpect(status().isOk()); - MvcResult mvcResult = mockMvc.perform(get(ROOT_URL)) + MvcResult mvcResult = mockMvc.perform(get(ROOT_URL + GET_ALL_AUDIT_PARAMS)) .andExpect(status().isOk()) .andReturn(); diff --git a/src/main/java/uk/gov/hmcts/reform/pip/account/management/controllers/AuditController.java b/src/main/java/uk/gov/hmcts/reform/pip/account/management/controllers/AuditController.java index 236c6fe69..d2ab0c1dd 100644 --- a/src/main/java/uk/gov/hmcts/reform/pip/account/management/controllers/AuditController.java +++ b/src/main/java/uk/gov/hmcts/reform/pip/account/management/controllers/AuditController.java @@ -9,6 +9,7 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; +import org.springframework.format.annotation.DateTimeFormat; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; @@ -21,7 +22,10 @@ import uk.gov.hmcts.reform.pip.account.management.model.AuditLog; import uk.gov.hmcts.reform.pip.account.management.service.AuditService; import uk.gov.hmcts.reform.pip.model.authentication.roles.IsAdmin; +import uk.gov.hmcts.reform.pip.model.enums.AuditAction; +import java.time.LocalDateTime; +import java.util.List; import java.util.UUID; import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; @@ -45,14 +49,22 @@ public AuditController(AuditService auditService) { this.auditService = auditService; } - @ApiResponse(responseCode = OK_ERROR_CODE, description = "All audit logs returned as a page.") + @ApiResponse(responseCode = OK_ERROR_CODE, description = "All audit logs returned as a page with filtering.") @Operation(summary = "Get all audit logs returned as a page") @GetMapping public ResponseEntity> getAllAuditLogs( @RequestParam(name = "pageNumber", defaultValue = "0") int pageNumber, - @RequestParam(name = "pageSize", defaultValue = "25") int pageSize) { + @RequestParam(name = "pageSize", defaultValue = "25") int pageSize, + @RequestParam(name = "email", defaultValue = "", required = false) String email, + @RequestParam(name = "userId", defaultValue = "", required = false) String userId, + @RequestParam(name = "actions", defaultValue = "", required = false) List auditActions, + @RequestParam(name = "filterStartDate", defaultValue = "") + @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime filterStartDate, + @RequestParam(name = "filterEndDate", defaultValue = "") + @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime filterEndDate) { Pageable pageable = PageRequest.of(pageNumber, pageSize); - return ResponseEntity.ok(auditService.getAllAuditLogs(pageable)); + return ResponseEntity.ok(auditService.getAllAuditLogs(pageable, email, userId, + auditActions, filterStartDate, filterEndDate)); } @ApiResponse(responseCode = OK_ERROR_CODE, description = "Audit log with id {id} returned.") diff --git a/src/main/java/uk/gov/hmcts/reform/pip/account/management/database/AuditRepository.java b/src/main/java/uk/gov/hmcts/reform/pip/account/management/database/AuditRepository.java index b1cb9d9a2..a9e1bc417 100644 --- a/src/main/java/uk/gov/hmcts/reform/pip/account/management/database/AuditRepository.java +++ b/src/main/java/uk/gov/hmcts/reform/pip/account/management/database/AuditRepository.java @@ -5,8 +5,10 @@ import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.transaction.annotation.Transactional; import uk.gov.hmcts.reform.pip.account.management.model.AuditLog; +import uk.gov.hmcts.reform.pip.model.enums.AuditAction; import java.time.LocalDateTime; +import java.util.List; import java.util.UUID; public interface AuditRepository extends JpaRepository { @@ -14,5 +16,11 @@ public interface AuditRepository extends JpaRepository { @Transactional void deleteAllByTimestampBefore(LocalDateTime timestamp); - Page findAllByOrderByTimestampDesc(Pageable pageable); + Page findAllByUserEmailLikeIgnoreCaseAndUserIdLikeAndActionInAndTimestampBetweenOrderByTimestampDesc( + String email, + String userId, + List auditAction, + LocalDateTime timeStampFrom, + LocalDateTime timeStampTo, + Pageable pageable); } diff --git a/src/main/java/uk/gov/hmcts/reform/pip/account/management/service/AuditService.java b/src/main/java/uk/gov/hmcts/reform/pip/account/management/service/AuditService.java index b9b37eee3..6ef4a2960 100644 --- a/src/main/java/uk/gov/hmcts/reform/pip/account/management/service/AuditService.java +++ b/src/main/java/uk/gov/hmcts/reform/pip/account/management/service/AuditService.java @@ -8,8 +8,12 @@ import uk.gov.hmcts.reform.pip.account.management.database.AuditRepository; import uk.gov.hmcts.reform.pip.account.management.errorhandling.exceptions.NotFoundException; import uk.gov.hmcts.reform.pip.account.management.model.AuditLog; +import uk.gov.hmcts.reform.pip.model.enums.AuditAction; import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.EnumSet; +import java.util.List; import java.util.UUID; /** @@ -33,8 +37,35 @@ public AuditService(AuditRepository auditRepository) { * @param pageable The pageable object to query by. * @return Returns the audit logs in a page. */ - public Page getAllAuditLogs(Pageable pageable) { - return auditRepository.findAllByOrderByTimestampDesc(pageable); + public Page getAllAuditLogs(Pageable pageable, String email, String userId, + List auditActions, LocalDateTime filterStartDate, LocalDateTime filterEndDate) { + + // If email address is supplied then find by an exact match + String userEmailAddressToQuery = "%%"; + if (!email.isBlank()) { + userEmailAddressToQuery = email; + } + + // If user provenance id is supplied then find by an exact match + String userIdToQuery = "%%"; + if (!userId.isBlank()) { + userIdToQuery = userId; + } + + // If user audit action is supplied then find by an exact match + List auditActionsToQuery = new ArrayList<>(EnumSet.allOf(AuditAction.class)); + if (!auditActions.isEmpty()) { + auditActionsToQuery = auditActions; + } + + return auditRepository + .findAllByUserEmailLikeIgnoreCaseAndUserIdLikeAndActionInAndTimestampBetweenOrderByTimestampDesc( + userEmailAddressToQuery, + userIdToQuery, + auditActionsToQuery, + filterStartDate, + filterEndDate, + pageable); } public AuditLog getAuditLogById(UUID id) { diff --git a/src/test/java/uk/gov/hmcts/reform/pip/account/management/controllers/AuditControllerTest.java b/src/test/java/uk/gov/hmcts/reform/pip/account/management/controllers/AuditControllerTest.java index bc1eb5ad1..157d78ae4 100644 --- a/src/test/java/uk/gov/hmcts/reform/pip/account/management/controllers/AuditControllerTest.java +++ b/src/test/java/uk/gov/hmcts/reform/pip/account/management/controllers/AuditControllerTest.java @@ -14,6 +14,9 @@ import uk.gov.hmcts.reform.pip.model.account.UserProvenances; import uk.gov.hmcts.reform.pip.model.enums.AuditAction; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; import java.util.UUID; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -29,11 +32,16 @@ class AuditControllerTest { private AuditController auditController; private static final String STATUS_CODE_MATCH = "Status code responses should match"; + private static final String EMAIL = "a@b.com"; + private static final String USER_ID = "123"; + private static final List AUDIT_ACTIONS = new ArrayList<>(); + private static final LocalDateTime FILTER_START_DATE = LocalDateTime.now(); + private static final LocalDateTime FILTER_END_DATE = LocalDateTime.now(); @Test void testGetAllAuditLogs() { - ResponseEntity> response = auditController.getAllAuditLogs(0, 25); - + ResponseEntity> response = auditController.getAllAuditLogs(0, 25, + EMAIL, USER_ID, AUDIT_ACTIONS, FILTER_START_DATE, FILTER_END_DATE); assertEquals(HttpStatus.OK, response.getStatusCode(), STATUS_CODE_MATCH); } diff --git a/src/test/java/uk/gov/hmcts/reform/pip/account/management/service/AuditServiceTest.java b/src/test/java/uk/gov/hmcts/reform/pip/account/management/service/AuditServiceTest.java index 906e46871..3255d7dc0 100644 --- a/src/test/java/uk/gov/hmcts/reform/pip/account/management/service/AuditServiceTest.java +++ b/src/test/java/uk/gov/hmcts/reform/pip/account/management/service/AuditServiceTest.java @@ -16,6 +16,7 @@ import uk.gov.hmcts.reform.pip.model.enums.AuditAction; import java.time.LocalDateTime; +import java.util.ArrayList; import java.util.List; import java.util.Optional; import java.util.UUID; @@ -38,6 +39,11 @@ class AuditServiceTest { @InjectMocks private AuditService auditService; + private static final String EMAIL = "a@b.com"; + private static final String USER_ID = "123"; + private static final List AUDIT_ACTIONS = new ArrayList<>(); + private static final LocalDateTime FILTER_START_DATE = LocalDateTime.now(); + private static final LocalDateTime FILTER_END_DATE = LocalDateTime.now(); private final AuditLog auditLogExample = new AuditLog(); @BeforeEach @@ -48,15 +54,20 @@ void setup() { auditLogExample.setAction(AuditAction.MANAGE_USER); auditLogExample.setDetails("Test details for manage user"); auditLogExample.setTimestamp(LocalDateTime.now()); + + AUDIT_ACTIONS.add(AuditAction.ADMIN_CREATION); } @Test void testGetAllAuditLogs() { Pageable pageable = PageRequest.of(0, 25); Page page = new PageImpl<>(List.of(auditLogExample), pageable, List.of(auditLogExample).size()); - when(auditRepository.findAllByOrderByTimestampDesc(pageable)).thenReturn(page); + when(auditRepository + .findAllByUserEmailLikeIgnoreCaseAndUserIdLikeAndActionInAndTimestampBetweenOrderByTimestampDesc( + EMAIL, USER_ID, AUDIT_ACTIONS, FILTER_START_DATE, FILTER_END_DATE, pageable)).thenReturn(page); - Page returnedAuditLogs = auditService.getAllAuditLogs(pageable); + Page returnedAuditLogs = auditService.getAllAuditLogs(pageable, EMAIL, USER_ID, AUDIT_ACTIONS, + FILTER_START_DATE, FILTER_END_DATE); assertEquals(auditLogExample, returnedAuditLogs.getContent().get(0), "Returned audit log does not match the expected"); From 2045fc86075fe6e6b9821920283fe1ef34f70786 Mon Sep 17 00:00:00 2001 From: junaidiqbalmoj Date: Wed, 27 Nov 2024 09:43:42 +0000 Subject: [PATCH 2/6] fix code review comment --- .../pip/account/management/service/AuditService.java | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/main/java/uk/gov/hmcts/reform/pip/account/management/service/AuditService.java b/src/main/java/uk/gov/hmcts/reform/pip/account/management/service/AuditService.java index 6ef4a2960..0daf5c973 100644 --- a/src/main/java/uk/gov/hmcts/reform/pip/account/management/service/AuditService.java +++ b/src/main/java/uk/gov/hmcts/reform/pip/account/management/service/AuditService.java @@ -40,12 +40,6 @@ public AuditService(AuditRepository auditRepository) { public Page getAllAuditLogs(Pageable pageable, String email, String userId, List auditActions, LocalDateTime filterStartDate, LocalDateTime filterEndDate) { - // If email address is supplied then find by an exact match - String userEmailAddressToQuery = "%%"; - if (!email.isBlank()) { - userEmailAddressToQuery = email; - } - // If user provenance id is supplied then find by an exact match String userIdToQuery = "%%"; if (!userId.isBlank()) { @@ -60,7 +54,7 @@ public Page getAllAuditLogs(Pageable pageable, String email, String us return auditRepository .findAllByUserEmailLikeIgnoreCaseAndUserIdLikeAndActionInAndTimestampBetweenOrderByTimestampDesc( - userEmailAddressToQuery, + "%" + email + "%", userIdToQuery, auditActionsToQuery, filterStartDate, From 8b1f4825408571e06af76f0b12b45cbe4d66e5c0 Mon Sep 17 00:00:00 2001 From: junaidiqbalmoj Date: Wed, 27 Nov 2024 09:57:58 +0000 Subject: [PATCH 3/6] fix test --- .../pip/account/management/service/AuditServiceTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/test/java/uk/gov/hmcts/reform/pip/account/management/service/AuditServiceTest.java b/src/test/java/uk/gov/hmcts/reform/pip/account/management/service/AuditServiceTest.java index 3255d7dc0..366c5f08a 100644 --- a/src/test/java/uk/gov/hmcts/reform/pip/account/management/service/AuditServiceTest.java +++ b/src/test/java/uk/gov/hmcts/reform/pip/account/management/service/AuditServiceTest.java @@ -64,7 +64,8 @@ void testGetAllAuditLogs() { Page page = new PageImpl<>(List.of(auditLogExample), pageable, List.of(auditLogExample).size()); when(auditRepository .findAllByUserEmailLikeIgnoreCaseAndUserIdLikeAndActionInAndTimestampBetweenOrderByTimestampDesc( - EMAIL, USER_ID, AUDIT_ACTIONS, FILTER_START_DATE, FILTER_END_DATE, pageable)).thenReturn(page); + "%" + EMAIL + "%", USER_ID, AUDIT_ACTIONS, FILTER_START_DATE, FILTER_END_DATE, pageable)) + .thenReturn(page); Page returnedAuditLogs = auditService.getAllAuditLogs(pageable, EMAIL, USER_ID, AUDIT_ACTIONS, FILTER_START_DATE, FILTER_END_DATE); From a0c97394964a22b0c916437232de1028bef6c180 Mon Sep 17 00:00:00 2001 From: junaidiqbalmoj Date: Thu, 28 Nov 2024 10:51:46 +0000 Subject: [PATCH 4/6] Make filter date param as optional --- .../management/controllers/AuditTest.java | 4 +-- .../controllers/AuditController.java | 9 ++---- .../management/database/AuditRepository.java | 6 ++++ .../management/service/AuditService.java | 30 +++++++++++++---- .../controllers/AuditControllerTest.java | 6 ++-- .../management/service/AuditServiceTest.java | 32 ++++++++++++++++--- 6 files changed, 61 insertions(+), 26 deletions(-) diff --git a/src/integrationTest/java/uk/gov/hmcts/reform/pip/account/management/controllers/AuditTest.java b/src/integrationTest/java/uk/gov/hmcts/reform/pip/account/management/controllers/AuditTest.java index 426d9dc9e..eae6f2537 100644 --- a/src/integrationTest/java/uk/gov/hmcts/reform/pip/account/management/controllers/AuditTest.java +++ b/src/integrationTest/java/uk/gov/hmcts/reform/pip/account/management/controllers/AuditTest.java @@ -52,8 +52,6 @@ class AuditTest { private static final String UNAUTHORIZED_USERNAME = "unauthorized_isAuthorized"; private static final String FORBIDDEN_STATUS_CODE = "Status code does not match forbidden"; private static final String GET_AUDIT_LOG_FAILED = "Failed to retrieve audit log"; - private static final String GET_ALL_AUDIT_PARAMS = - "?filterStartDate=2020-01-01T00:00:00.000Z&filterEndDate=2100-01-01T00:00:00.000Z"; private static final AuditAction AUDIT_ACTION = AuditAction.MANAGE_THIRD_PARTY_USER_VIEW; private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); @@ -96,7 +94,7 @@ void testGetAllAuditLogs() throws Exception { .contentType(MediaType.APPLICATION_JSON); mockMvc.perform(mockHttpServletRequestBuilder2).andExpect(status().isOk()); - MvcResult mvcResult = mockMvc.perform(get(ROOT_URL + GET_ALL_AUDIT_PARAMS)) + MvcResult mvcResult = mockMvc.perform(get(ROOT_URL)) .andExpect(status().isOk()) .andReturn(); diff --git a/src/main/java/uk/gov/hmcts/reform/pip/account/management/controllers/AuditController.java b/src/main/java/uk/gov/hmcts/reform/pip/account/management/controllers/AuditController.java index d2ab0c1dd..2750e959e 100644 --- a/src/main/java/uk/gov/hmcts/reform/pip/account/management/controllers/AuditController.java +++ b/src/main/java/uk/gov/hmcts/reform/pip/account/management/controllers/AuditController.java @@ -9,7 +9,6 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; -import org.springframework.format.annotation.DateTimeFormat; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; @@ -24,7 +23,6 @@ import uk.gov.hmcts.reform.pip.model.authentication.roles.IsAdmin; import uk.gov.hmcts.reform.pip.model.enums.AuditAction; -import java.time.LocalDateTime; import java.util.List; import java.util.UUID; @@ -58,13 +56,10 @@ public ResponseEntity> getAllAuditLogs( @RequestParam(name = "email", defaultValue = "", required = false) String email, @RequestParam(name = "userId", defaultValue = "", required = false) String userId, @RequestParam(name = "actions", defaultValue = "", required = false) List auditActions, - @RequestParam(name = "filterStartDate", defaultValue = "") - @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime filterStartDate, - @RequestParam(name = "filterEndDate", defaultValue = "") - @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime filterEndDate) { + @RequestParam(name = "filterDate", defaultValue = "", required = false) String filterDate) { Pageable pageable = PageRequest.of(pageNumber, pageSize); return ResponseEntity.ok(auditService.getAllAuditLogs(pageable, email, userId, - auditActions, filterStartDate, filterEndDate)); + auditActions, filterDate)); } @ApiResponse(responseCode = OK_ERROR_CODE, description = "Audit log with id {id} returned.") diff --git a/src/main/java/uk/gov/hmcts/reform/pip/account/management/database/AuditRepository.java b/src/main/java/uk/gov/hmcts/reform/pip/account/management/database/AuditRepository.java index a9e1bc417..69ba59ac8 100644 --- a/src/main/java/uk/gov/hmcts/reform/pip/account/management/database/AuditRepository.java +++ b/src/main/java/uk/gov/hmcts/reform/pip/account/management/database/AuditRepository.java @@ -16,6 +16,12 @@ public interface AuditRepository extends JpaRepository { @Transactional void deleteAllByTimestampBefore(LocalDateTime timestamp); + Page findAllByUserEmailLikeIgnoreCaseAndUserIdLikeAndActionInOrderByTimestampDesc( + String email, + String userId, + List auditAction, + Pageable pageable); + Page findAllByUserEmailLikeIgnoreCaseAndUserIdLikeAndActionInAndTimestampBetweenOrderByTimestampDesc( String email, String userId, diff --git a/src/main/java/uk/gov/hmcts/reform/pip/account/management/service/AuditService.java b/src/main/java/uk/gov/hmcts/reform/pip/account/management/service/AuditService.java index 0daf5c973..364b98a8f 100644 --- a/src/main/java/uk/gov/hmcts/reform/pip/account/management/service/AuditService.java +++ b/src/main/java/uk/gov/hmcts/reform/pip/account/management/service/AuditService.java @@ -10,7 +10,10 @@ import uk.gov.hmcts.reform.pip.account.management.model.AuditLog; import uk.gov.hmcts.reform.pip.model.enums.AuditAction; +import java.time.LocalDate; import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.EnumSet; import java.util.List; @@ -38,7 +41,7 @@ public AuditService(AuditRepository auditRepository) { * @return Returns the audit logs in a page. */ public Page getAllAuditLogs(Pageable pageable, String email, String userId, - List auditActions, LocalDateTime filterStartDate, LocalDateTime filterEndDate) { + List auditActions, String filterDate) { // If user provenance id is supplied then find by an exact match String userIdToQuery = "%%"; @@ -52,14 +55,27 @@ public Page getAllAuditLogs(Pageable pageable, String email, String us auditActionsToQuery = auditActions; } + if (filterDate.isBlank()) { + return auditRepository + .findAllByUserEmailLikeIgnoreCaseAndUserIdLikeAndActionInOrderByTimestampDesc( + "%" + email + "%", + userIdToQuery, + auditActionsToQuery, + pageable); + } + + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + LocalDateTime filterStartDate = LocalDate.parse(filterDate, formatter).atTime(LocalTime.MIN); + LocalDateTime filterEndDate = LocalDate.parse(filterDate, formatter).atTime(LocalTime.MAX); + return auditRepository .findAllByUserEmailLikeIgnoreCaseAndUserIdLikeAndActionInAndTimestampBetweenOrderByTimestampDesc( - "%" + email + "%", - userIdToQuery, - auditActionsToQuery, - filterStartDate, - filterEndDate, - pageable); + "%" + email + "%", + userIdToQuery, + auditActionsToQuery, + filterStartDate, + filterEndDate, + pageable); } public AuditLog getAuditLogById(UUID id) { diff --git a/src/test/java/uk/gov/hmcts/reform/pip/account/management/controllers/AuditControllerTest.java b/src/test/java/uk/gov/hmcts/reform/pip/account/management/controllers/AuditControllerTest.java index 157d78ae4..ba34841b0 100644 --- a/src/test/java/uk/gov/hmcts/reform/pip/account/management/controllers/AuditControllerTest.java +++ b/src/test/java/uk/gov/hmcts/reform/pip/account/management/controllers/AuditControllerTest.java @@ -14,7 +14,6 @@ import uk.gov.hmcts.reform.pip.model.account.UserProvenances; import uk.gov.hmcts.reform.pip.model.enums.AuditAction; -import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; import java.util.UUID; @@ -35,13 +34,12 @@ class AuditControllerTest { private static final String EMAIL = "a@b.com"; private static final String USER_ID = "123"; private static final List AUDIT_ACTIONS = new ArrayList<>(); - private static final LocalDateTime FILTER_START_DATE = LocalDateTime.now(); - private static final LocalDateTime FILTER_END_DATE = LocalDateTime.now(); + private static final String FILTER_DATE = "2023-11-01"; @Test void testGetAllAuditLogs() { ResponseEntity> response = auditController.getAllAuditLogs(0, 25, - EMAIL, USER_ID, AUDIT_ACTIONS, FILTER_START_DATE, FILTER_END_DATE); + EMAIL, USER_ID, AUDIT_ACTIONS, FILTER_DATE); assertEquals(HttpStatus.OK, response.getStatusCode(), STATUS_CODE_MATCH); } diff --git a/src/test/java/uk/gov/hmcts/reform/pip/account/management/service/AuditServiceTest.java b/src/test/java/uk/gov/hmcts/reform/pip/account/management/service/AuditServiceTest.java index 366c5f08a..da2671760 100644 --- a/src/test/java/uk/gov/hmcts/reform/pip/account/management/service/AuditServiceTest.java +++ b/src/test/java/uk/gov/hmcts/reform/pip/account/management/service/AuditServiceTest.java @@ -15,7 +15,10 @@ import uk.gov.hmcts.reform.pip.account.management.model.AuditLog; import uk.gov.hmcts.reform.pip.model.enums.AuditAction; +import java.time.LocalDate; import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.List; import java.util.Optional; @@ -42,8 +45,7 @@ class AuditServiceTest { private static final String EMAIL = "a@b.com"; private static final String USER_ID = "123"; private static final List AUDIT_ACTIONS = new ArrayList<>(); - private static final LocalDateTime FILTER_START_DATE = LocalDateTime.now(); - private static final LocalDateTime FILTER_END_DATE = LocalDateTime.now(); + private static final String FILTER_DATE = "2024-11-01"; private final AuditLog auditLogExample = new AuditLog(); @BeforeEach @@ -63,12 +65,32 @@ void testGetAllAuditLogs() { Pageable pageable = PageRequest.of(0, 25); Page page = new PageImpl<>(List.of(auditLogExample), pageable, List.of(auditLogExample).size()); when(auditRepository - .findAllByUserEmailLikeIgnoreCaseAndUserIdLikeAndActionInAndTimestampBetweenOrderByTimestampDesc( - "%" + EMAIL + "%", USER_ID, AUDIT_ACTIONS, FILTER_START_DATE, FILTER_END_DATE, pageable)) + .findAllByUserEmailLikeIgnoreCaseAndUserIdLikeAndActionInOrderByTimestampDesc( + "%" + EMAIL + "%", USER_ID, AUDIT_ACTIONS, pageable)) .thenReturn(page); Page returnedAuditLogs = auditService.getAllAuditLogs(pageable, EMAIL, USER_ID, AUDIT_ACTIONS, - FILTER_START_DATE, FILTER_END_DATE); + ""); + + assertEquals(auditLogExample, returnedAuditLogs.getContent().get(0), + "Returned audit log does not match the expected"); + } + + @Test + void testGetAllAuditLogsWithFilterDate() { + Pageable pageable = PageRequest.of(0, 25); + Page page = new PageImpl<>(List.of(auditLogExample), pageable, List.of(auditLogExample).size()); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + LocalDateTime filterStartDate = LocalDate.parse(FILTER_DATE, formatter).atTime(LocalTime.MIN); + LocalDateTime filterEndDate = LocalDate.parse(FILTER_DATE, formatter).atTime(LocalTime.MAX); + + when(auditRepository + .findAllByUserEmailLikeIgnoreCaseAndUserIdLikeAndActionInAndTimestampBetweenOrderByTimestampDesc( + "%" + EMAIL + "%", USER_ID, AUDIT_ACTIONS, filterStartDate, filterEndDate, pageable)) + .thenReturn(page); + + Page returnedAuditLogs = auditService.getAllAuditLogs(pageable, EMAIL, USER_ID, AUDIT_ACTIONS, + FILTER_DATE); assertEquals(auditLogExample, returnedAuditLogs.getContent().get(0), "Returned audit log does not match the expected"); From d1d87eaf9574db14844f8ea540c79324d1f1dd01 Mon Sep 17 00:00:00 2001 From: junaidiqbalmoj Date: Thu, 28 Nov 2024 13:31:48 +0000 Subject: [PATCH 5/6] fix typo --- .../reform/pip/account/management/service/AuditService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/uk/gov/hmcts/reform/pip/account/management/service/AuditService.java b/src/main/java/uk/gov/hmcts/reform/pip/account/management/service/AuditService.java index 364b98a8f..be70fd6a7 100644 --- a/src/main/java/uk/gov/hmcts/reform/pip/account/management/service/AuditService.java +++ b/src/main/java/uk/gov/hmcts/reform/pip/account/management/service/AuditService.java @@ -43,7 +43,7 @@ public AuditService(AuditRepository auditRepository) { public Page getAllAuditLogs(Pageable pageable, String email, String userId, List auditActions, String filterDate) { - // If user provenance id is supplied then find by an exact match + // If user id is supplied then find by an exact match String userIdToQuery = "%%"; if (!userId.isBlank()) { userIdToQuery = userId; From be2cac9ff3aacf8898c42ae40bd4bab0d10f3480 Mon Sep 17 00:00:00 2001 From: junaidiqbalmoj Date: Tue, 3 Dec 2024 12:21:08 +0000 Subject: [PATCH 6/6] add integration tests --- .../management/controllers/AuditTest.java | 264 ++++++++++++++++++ 1 file changed, 264 insertions(+) diff --git a/src/integrationTest/java/uk/gov/hmcts/reform/pip/account/management/controllers/AuditTest.java b/src/integrationTest/java/uk/gov/hmcts/reform/pip/account/management/controllers/AuditTest.java index eae6f2537..0455a5837 100644 --- a/src/integrationTest/java/uk/gov/hmcts/reform/pip/account/management/controllers/AuditTest.java +++ b/src/integrationTest/java/uk/gov/hmcts/reform/pip/account/management/controllers/AuditTest.java @@ -24,6 +24,9 @@ import uk.gov.hmcts.reform.pip.model.account.UserProvenances; import uk.gov.hmcts.reform.pip.model.enums.AuditAction; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; + import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.springframework.http.HttpStatus.FORBIDDEN; @@ -43,6 +46,7 @@ class AuditTest { private static final String ROOT_URL = "/audit"; private static final String EMAIL = "test_account_admin@hmcts.net"; + private static final String ADDITIONAL_USER_EMAIL = "test_account_admin_2@hmcts.net"; private static final Roles ROLES = Roles.SYSTEM_ADMIN; private static final UserProvenances USER_PROVENANCE = UserProvenances.PI_AAD; private static final String AUDIT_DETAILS = "User requested to view all third party users"; @@ -53,6 +57,8 @@ class AuditTest { private static final String FORBIDDEN_STATUS_CODE = "Status code does not match forbidden"; private static final String GET_AUDIT_LOG_FAILED = "Failed to retrieve audit log"; private static final AuditAction AUDIT_ACTION = AuditAction.MANAGE_THIRD_PARTY_USER_VIEW; + private static final AuditAction ADDITIONAL_USER_AUDIT_ACTION = AuditAction.MANAGE_USER; + private static final String ADDITIONAL_USER_AUDIT_DETAILS = "Manage user"; private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); @@ -117,6 +123,264 @@ void testGetAllAuditLogs() throws Exception { assertEquals(AUDIT_DETAILS, auditLog2.getDetails(), GET_AUDIT_LOG_FAILED); } + @Test + void testGetAllAuditLogsFilterByEmail() throws Exception { + MockHttpServletRequestBuilder mockHttpServletRequestBuilder1 = MockMvcRequestBuilders + .post(ROOT_URL) + .content(OBJECT_MAPPER.writeValueAsString(createAuditLog())) + .contentType(MediaType.APPLICATION_JSON); + + mockMvc.perform(mockHttpServletRequestBuilder1).andExpect(status().isOk()); + + MockHttpServletRequestBuilder mockHttpServletRequestBuilder2 = MockMvcRequestBuilders + .post(ROOT_URL) + .content(OBJECT_MAPPER.writeValueAsString(new AuditLog( + ADDITIONAL_USER_ID, + ADDITIONAL_USER_EMAIL, + ROLES, + USER_PROVENANCE, + AUDIT_ACTION, + AUDIT_DETAILS + ))) + .contentType(MediaType.APPLICATION_JSON); + mockMvc.perform(mockHttpServletRequestBuilder2).andExpect(status().isOk()); + + MvcResult mvcResult = mockMvc.perform(get(ROOT_URL + "?email=" + EMAIL)) + .andExpect(status().isOk()) + .andReturn(); + + CustomPageImpl pageResponse = + OBJECT_MAPPER.readValue( + mvcResult.getResponse().getContentAsString(), + new TypeReference<>() { + } + ); + AuditLog auditLog1 = pageResponse.getContent().get(0); + + assertEquals(EMAIL, auditLog1.getUserEmail(), GET_AUDIT_LOG_FAILED); + assertEquals(USER_ID, auditLog1.getUserId(), GET_AUDIT_LOG_FAILED); + assertEquals(AUDIT_DETAILS, auditLog1.getDetails(), GET_AUDIT_LOG_FAILED); + } + + @Test + void testGetAllAuditLogsPartialEmailFilter() throws Exception { + MockHttpServletRequestBuilder mockHttpServletRequestBuilder1 = MockMvcRequestBuilders + .post(ROOT_URL) + .content(OBJECT_MAPPER.writeValueAsString(createAuditLog())) + .contentType(MediaType.APPLICATION_JSON); + + mockMvc.perform(mockHttpServletRequestBuilder1).andExpect(status().isOk()); + + MockHttpServletRequestBuilder mockHttpServletRequestBuilder2 = MockMvcRequestBuilders + .post(ROOT_URL) + .content(OBJECT_MAPPER.writeValueAsString(new AuditLog( + ADDITIONAL_USER_ID, + EMAIL, + ROLES, + USER_PROVENANCE, + AUDIT_ACTION, + AUDIT_DETAILS + ))) + .contentType(MediaType.APPLICATION_JSON); + mockMvc.perform(mockHttpServletRequestBuilder2).andExpect(status().isOk()); + + MvcResult mvcResult = mockMvc.perform(get(ROOT_URL + "?email=test_account_admin")) + .andExpect(status().isOk()) + .andReturn(); + + CustomPageImpl pageResponse = + OBJECT_MAPPER.readValue( + mvcResult.getResponse().getContentAsString(), + new TypeReference<>() { + } + ); + + AuditLog auditLog1 = pageResponse.getContent().get(0); + + assertEquals(EMAIL, auditLog1.getUserEmail(), GET_AUDIT_LOG_FAILED); + assertEquals(ADDITIONAL_USER_ID, auditLog1.getUserId(), GET_AUDIT_LOG_FAILED); + assertEquals(AUDIT_DETAILS, auditLog1.getDetails(), GET_AUDIT_LOG_FAILED); + + AuditLog auditLog2 = pageResponse.getContent().get(1); + + assertEquals(EMAIL, auditLog2.getUserEmail(), GET_AUDIT_LOG_FAILED); + assertEquals(USER_ID, auditLog2.getUserId(), GET_AUDIT_LOG_FAILED); + assertEquals(AUDIT_DETAILS, auditLog2.getDetails(), GET_AUDIT_LOG_FAILED); + } + + @Test + void testGetAllAuditLogsFilterByUserId() throws Exception { + MockHttpServletRequestBuilder mockHttpServletRequestBuilder1 = MockMvcRequestBuilders + .post(ROOT_URL) + .content(OBJECT_MAPPER.writeValueAsString(createAuditLog())) + .contentType(MediaType.APPLICATION_JSON); + + mockMvc.perform(mockHttpServletRequestBuilder1).andExpect(status().isOk()); + + MockHttpServletRequestBuilder mockHttpServletRequestBuilder2 = MockMvcRequestBuilders + .post(ROOT_URL) + .content(OBJECT_MAPPER.writeValueAsString(new AuditLog( + ADDITIONAL_USER_ID, + ADDITIONAL_USER_EMAIL, + ROLES, + USER_PROVENANCE, + AUDIT_ACTION, + AUDIT_DETAILS + ))) + .contentType(MediaType.APPLICATION_JSON); + mockMvc.perform(mockHttpServletRequestBuilder2).andExpect(status().isOk()); + + MvcResult mvcResult = mockMvc.perform(get(ROOT_URL + "?userId=" + ADDITIONAL_USER_ID)) + .andExpect(status().isOk()) + .andReturn(); + + CustomPageImpl pageResponse = + OBJECT_MAPPER.readValue( + mvcResult.getResponse().getContentAsString(), + new TypeReference<>() { + } + ); + AuditLog auditLog1 = pageResponse.getContent().get(0); + + assertEquals(ADDITIONAL_USER_EMAIL, auditLog1.getUserEmail(), GET_AUDIT_LOG_FAILED); + assertEquals(ADDITIONAL_USER_ID, auditLog1.getUserId(), GET_AUDIT_LOG_FAILED); + assertEquals(AUDIT_DETAILS, auditLog1.getDetails(), GET_AUDIT_LOG_FAILED); + } + + @Test + void testGetAllAuditLogsFilterByAuditAction() throws Exception { + MockHttpServletRequestBuilder mockHttpServletRequestBuilder1 = MockMvcRequestBuilders + .post(ROOT_URL) + .content(OBJECT_MAPPER.writeValueAsString(createAuditLog())) + .contentType(MediaType.APPLICATION_JSON); + + mockMvc.perform(mockHttpServletRequestBuilder1).andExpect(status().isOk()); + + MockHttpServletRequestBuilder mockHttpServletRequestBuilder2 = MockMvcRequestBuilders + .post(ROOT_URL) + .content(OBJECT_MAPPER.writeValueAsString(new AuditLog( + ADDITIONAL_USER_ID, + ADDITIONAL_USER_EMAIL, + ROLES, + USER_PROVENANCE, + ADDITIONAL_USER_AUDIT_ACTION, + ADDITIONAL_USER_AUDIT_DETAILS + ))) + .contentType(MediaType.APPLICATION_JSON); + mockMvc.perform(mockHttpServletRequestBuilder2).andExpect(status().isOk()); + + MvcResult mvcResult = mockMvc.perform(get(ROOT_URL + "?actions=" + ADDITIONAL_USER_AUDIT_ACTION)) + .andExpect(status().isOk()) + .andReturn(); + + CustomPageImpl pageResponse = + OBJECT_MAPPER.readValue( + mvcResult.getResponse().getContentAsString(), + new TypeReference<>() { + } + ); + AuditLog auditLog1 = pageResponse.getContent().get(0); + + + assertEquals(pageResponse.getContent().size(), 1, GET_AUDIT_LOG_FAILED); + assertEquals(ADDITIONAL_USER_EMAIL, auditLog1.getUserEmail(), GET_AUDIT_LOG_FAILED); + assertEquals(ADDITIONAL_USER_ID, auditLog1.getUserId(), GET_AUDIT_LOG_FAILED); + assertEquals(ADDITIONAL_USER_AUDIT_DETAILS, auditLog1.getDetails(), GET_AUDIT_LOG_FAILED); + } + + @Test + void testGetAllAuditLogsFilterByDate() throws Exception { + MockHttpServletRequestBuilder mockHttpServletRequestBuilder1 = MockMvcRequestBuilders + .post(ROOT_URL) + .content(OBJECT_MAPPER.writeValueAsString(createAuditLog())) + .contentType(MediaType.APPLICATION_JSON); + + mockMvc.perform(mockHttpServletRequestBuilder1).andExpect(status().isOk()); + + MockHttpServletRequestBuilder mockHttpServletRequestBuilder2 = MockMvcRequestBuilders + .post(ROOT_URL) + .content(OBJECT_MAPPER.writeValueAsString(new AuditLog( + ADDITIONAL_USER_ID, + ADDITIONAL_USER_EMAIL, + ROLES, + USER_PROVENANCE, + ADDITIONAL_USER_AUDIT_ACTION, + ADDITIONAL_USER_AUDIT_DETAILS + ))) + .contentType(MediaType.APPLICATION_JSON); + mockMvc.perform(mockHttpServletRequestBuilder2).andExpect(status().isOk()); + + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + LocalDate filterDate = LocalDate.parse(LocalDate.now().toString(), formatter); + + MvcResult mvcResult = mockMvc.perform(get(ROOT_URL + "?filterDate=" + filterDate)) + .andExpect(status().isOk()) + .andReturn(); + + CustomPageImpl pageResponse = + OBJECT_MAPPER.readValue( + mvcResult.getResponse().getContentAsString(), + new TypeReference<>() { + } + ); + + AuditLog auditLog1 = pageResponse.getContent().get(0); + + assertEquals(ADDITIONAL_USER_EMAIL, auditLog1.getUserEmail(), GET_AUDIT_LOG_FAILED); + assertEquals(ADDITIONAL_USER_ID, auditLog1.getUserId(), GET_AUDIT_LOG_FAILED); + assertEquals(ADDITIONAL_USER_AUDIT_DETAILS, auditLog1.getDetails(), GET_AUDIT_LOG_FAILED); + + AuditLog auditLog2 = pageResponse.getContent().get(1); + + assertEquals(EMAIL, auditLog2.getUserEmail(), GET_AUDIT_LOG_FAILED); + assertEquals(USER_ID, auditLog2.getUserId(), GET_AUDIT_LOG_FAILED); + assertEquals(AUDIT_DETAILS, auditLog2.getDetails(), GET_AUDIT_LOG_FAILED); + } + + @Test + void testGetAllAuditLogsFilterByEmailAndUserIdAndAuditActionAndDate() throws Exception { + MockHttpServletRequestBuilder mockHttpServletRequestBuilder1 = MockMvcRequestBuilders + .post(ROOT_URL) + .content(OBJECT_MAPPER.writeValueAsString(createAuditLog())) + .contentType(MediaType.APPLICATION_JSON); + + mockMvc.perform(mockHttpServletRequestBuilder1).andExpect(status().isOk()); + + MockHttpServletRequestBuilder mockHttpServletRequestBuilder2 = MockMvcRequestBuilders + .post(ROOT_URL) + .content(OBJECT_MAPPER.writeValueAsString(new AuditLog( + ADDITIONAL_USER_ID, + ADDITIONAL_USER_EMAIL, + ROLES, + USER_PROVENANCE, + ADDITIONAL_USER_AUDIT_ACTION, + ADDITIONAL_USER_AUDIT_DETAILS + ))) + .contentType(MediaType.APPLICATION_JSON); + mockMvc.perform(mockHttpServletRequestBuilder2).andExpect(status().isOk()); + + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + LocalDate filterDate = LocalDate.parse(LocalDate.now().toString(), formatter); + + MvcResult mvcResult = mockMvc.perform(get(ROOT_URL + "?email=" + ADDITIONAL_USER_EMAIL + + "&userId=" + ADDITIONAL_USER_ID + "&actions=" + ADDITIONAL_USER_AUDIT_ACTION + + "&filterDate=" + filterDate)) + .andExpect(status().isOk()) + .andReturn(); + + CustomPageImpl pageResponse = + OBJECT_MAPPER.readValue( + mvcResult.getResponse().getContentAsString(), + new TypeReference<>() { + } + ); + AuditLog auditLog1 = pageResponse.getContent().get(0); + + assertEquals(ADDITIONAL_USER_EMAIL, auditLog1.getUserEmail(), GET_AUDIT_LOG_FAILED); + assertEquals(ADDITIONAL_USER_ID, auditLog1.getUserId(), GET_AUDIT_LOG_FAILED); + assertEquals(ADDITIONAL_USER_AUDIT_DETAILS, auditLog1.getDetails(), GET_AUDIT_LOG_FAILED); + } + @Test @WithMockUser(username = UNAUTHORIZED_USERNAME, authorities = {UNAUTHORIZED_ROLE}) void testUnauthorizedGetAllAuditLogs() throws Exception {