Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PUB-1909 View Audit Logs #451

Merged
merged 9 commits into from
Dec 18, 2024
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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";
Expand All @@ -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();

Expand Down Expand Up @@ -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<AuditLog> 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<AuditLog> 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<AuditLog> 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<AuditLog> 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<AuditLog> 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<AuditLog> 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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@
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.util.List;
import java.util.UUID;

import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
Expand All @@ -45,14 +47,19 @@ 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<Page<AuditLog>> 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<AuditAction> auditActions,
@RequestParam(name = "filterDate", defaultValue = "", required = false) String filterDate) {
Pageable pageable = PageRequest.of(pageNumber, pageSize);
return ResponseEntity.ok(auditService.getAllAuditLogs(pageable));
return ResponseEntity.ok(auditService.getAllAuditLogs(pageable, email, userId,
auditActions, filterDate));
}

@ApiResponse(responseCode = OK_ERROR_CODE, description = "Audit log with id {id} returned.")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,28 @@
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<AuditLog, UUID> {

@Transactional
void deleteAllByTimestampBefore(LocalDateTime timestamp);

Page<AuditLog> findAllByOrderByTimestampDesc(Pageable pageable);
Page<AuditLog> findAllByUserEmailLikeIgnoreCaseAndUserIdLikeAndActionInOrderByTimestampDesc(
String email,
String userId,
List<AuditAction> auditAction,
Pageable pageable);

Page<AuditLog> findAllByUserEmailLikeIgnoreCaseAndUserIdLikeAndActionInAndTimestampBetweenOrderByTimestampDesc(
KianKwa marked this conversation as resolved.
Show resolved Hide resolved
String email,
String userId,
List<AuditAction> auditAction,
LocalDateTime timeStampFrom,
LocalDateTime timeStampTo,
Pageable pageable);
}
Loading
Loading