Commit 8c889778 authored by Riabokon Stanislav(EPAM)[GCP]'s avatar Riabokon Stanislav(EPAM)[GCP]
Browse files

Merge branch 'feature/GONRG-1607_Audit' into 'integration-master'

GONRG-1607 Audit Implementation.

See merge request go3-nrg/platform/System/partition!20
parents 56f560b1 380d240f
......@@ -14,6 +14,9 @@
package org.opengroup.osdu.partition.api;
import java.util.Collections;
import org.opengroup.osdu.partition.logging.AuditLogger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
......@@ -24,9 +27,14 @@ import org.springframework.web.bind.annotation.RestController;
@RequestMapping(path= "/_ah", produces = "application/json")
public class HealthCheck {
@Autowired
private AuditLogger auditLogger;
@GetMapping("/liveness_check")
public ResponseEntity<String> livenessCheck() {
return new ResponseEntity<>("Partition service is alive", HttpStatus.OK);
ResponseEntity responseEntity = new ResponseEntity<>("Partition service is alive", HttpStatus.OK);
this.auditLogger.readServiceLivenessSuccess(Collections.singletonList(responseEntity.toString()));
return responseEntity;
}
@GetMapping("/readiness_check")
......
......@@ -14,6 +14,8 @@
package org.opengroup.osdu.partition.api;
import java.util.Collections;
import org.opengroup.osdu.partition.logging.AuditLogger;
import org.opengroup.osdu.partition.model.PartitionInfo;
import org.opengroup.osdu.partition.model.Property;
import org.opengroup.osdu.partition.provider.interfaces.IPartitionService;
......@@ -40,11 +42,15 @@ public class PartitionApi {
@Qualifier("cachedPartitionServiceImpl")
private IPartitionService partitionService;
@Autowired
private AuditLogger auditLogger;
@PostMapping("/{partitionId}")
@PreAuthorize("@authorizationFilter.hasPermissions()")
public ResponseEntity create(@PathVariable("partitionId") String partitionId, @RequestBody @Valid PartitionInfo partitionInfo) {
this.partitionService.createPartition(partitionId, partitionInfo);
URI partitionLocation = ServletUriComponentsBuilder.fromCurrentRequest().buildAndExpand().toUri();
this.auditLogger.createdPartitionSuccess(Collections.singletonList(partitionId));
return ResponseEntity.created(partitionLocation).build();
}
......@@ -53,12 +59,14 @@ public class PartitionApi {
@ResponseStatus(HttpStatus.NO_CONTENT)
public void patch(@PathVariable("partitionId") String partitionId, @RequestBody @Valid PartitionInfo partitionInfo) {
this.partitionService.updatePartition(partitionId, partitionInfo);
this.auditLogger.updatedPartitionSecretSuccess(Collections.singletonList(partitionId));
}
@GetMapping("/{partitionId}")
@PreAuthorize("@authorizationFilter.hasPermissions()")
public ResponseEntity<Map<String, Property>> get(@PathVariable("partitionId") String partitionId) {
PartitionInfo partitionInfo = this.partitionService.getPartition(partitionId);
this.auditLogger.readPartitionSuccess(Collections.singletonList(partitionId));
return ResponseEntity.ok(partitionInfo.getProperties());
}
......@@ -66,6 +74,7 @@ public class PartitionApi {
@PreAuthorize("@authorizationFilter.hasPermissions()")
public ResponseEntity delete(@PathVariable("partitionId") String partitionId) {
this.partitionService.deletePartition(partitionId);
this.auditLogger.deletedPartitionSuccess(Collections.singletonList(partitionId));
return ResponseEntity.noContent().build();
}
......@@ -73,6 +82,8 @@ public class PartitionApi {
@PreAuthorize("@authorizationFilter.hasPermissions()")
public List<String> list() {
List<String> partitions = this.partitionService.getAllPartitions();
this.auditLogger.readListPartitionSuccess(
Collections.singletonList(String.format("Partition list size = %s", partitions.size())));
return partitions;
}
}
package org.opengroup.osdu.partition.logging;
import static java.lang.String.format;
import com.google.common.base.Strings;
import java.util.List;
import org.opengroup.osdu.core.common.logging.audit.AuditAction;
import org.opengroup.osdu.core.common.logging.audit.AuditPayload;
import org.opengroup.osdu.core.common.logging.audit.AuditStatus;
public class AuditEvents {
private static final String CREATE_PARTITION_ACTION_ID = "PT001";
private static final String CREATE_PARTITION_MESSAGE = "Partition creation";
private static final String READ_PARTITION_ACTION_ID = "PT002";
private static final String READ_PARTITION_MESSAGE = "Partition read";
private static final String DELETE_PARTITION_ACTION_ID = "PT003";
private static final String DELETE_PARTITION_MESSAGE = "Partition removal";
private static final String READ_SERVICE_LIVENESS_ACTION_ID = "PT004";
private static final String READ_SERVICE_LIVENESS_MESSAGE = "Service run";
private static final String UPDATE_PARTITION_ACTION_ID = "PT005";
private static final String UPDATE_PARTITION_MESSAGE = "Partition updating";
private static final String READ_LIST_PARTITION_ACTION_ID = "PT006";
private static final String READ_LIST_PARTITION_MESSAGE = "Partition list read";
private final String user;
public AuditEvents(String user) {
if (Strings.isNullOrEmpty(user)) {
throw new IllegalArgumentException("User not provided for audit events.");
}
this.user = user;
}
public AuditPayload getCreatePartitionEvent(AuditStatus status, List<String> resources) {
return AuditPayload.builder()
.action(AuditAction.CREATE)
.status(status)
.user(this.user)
.actionId(CREATE_PARTITION_ACTION_ID)
.message(getStatusMessage(status, CREATE_PARTITION_MESSAGE))
.resources(resources)
.build();
}
public AuditPayload getReadPartitionEvent(AuditStatus status, List<String> resources) {
return AuditPayload.builder()
.action(AuditAction.READ)
.status(status)
.user(this.user)
.actionId(READ_PARTITION_ACTION_ID)
.message(getStatusMessage(status, READ_PARTITION_MESSAGE))
.resources(resources)
.build();
}
public AuditPayload getDeletePartitionEvent(AuditStatus status, List<String> resources) {
return AuditPayload.builder()
.action(AuditAction.DELETE)
.status(status)
.user(this.user)
.actionId(DELETE_PARTITION_ACTION_ID)
.message(getStatusMessage(status, DELETE_PARTITION_MESSAGE))
.resources(resources)
.build();
}
public AuditPayload getReadServiceLivenessEvent(AuditStatus status, List<String> resources) {
return AuditPayload.builder()
.action(AuditAction.READ)
.status(status)
.user(this.user)
.actionId(READ_SERVICE_LIVENESS_ACTION_ID)
.message(getStatusMessage(status, READ_SERVICE_LIVENESS_MESSAGE))
.resources(resources)
.build();
}
public AuditPayload getUpdatePartitionSecretEvent(AuditStatus status, List<String> resources) {
return AuditPayload.builder()
.action(AuditAction.UPDATE)
.status(status)
.user(this.user)
.actionId(UPDATE_PARTITION_ACTION_ID)
.message(getStatusMessage(status, UPDATE_PARTITION_MESSAGE))
.resources(resources)
.build();
}
public AuditPayload getListPartitionEvent(AuditStatus status, List<String> resources) {
return AuditPayload.builder()
.action(AuditAction.READ)
.status(status)
.user(this.user)
.actionId(READ_LIST_PARTITION_ACTION_ID)
.message(getStatusMessage(status, READ_LIST_PARTITION_MESSAGE))
.resources(resources)
.build();
}
private String getStatusMessage(AuditStatus status, String message) {
return format("%s - %s", message, status.name().toLowerCase());
}
}
\ No newline at end of file
package org.opengroup.osdu.partition.logging;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.opengroup.osdu.core.common.logging.JaxRsDpsLog;
import org.opengroup.osdu.core.common.logging.audit.AuditPayload;
import org.opengroup.osdu.core.common.logging.audit.AuditStatus;
import org.opengroup.osdu.core.common.model.http.DpsHeaders;
import org.springframework.stereotype.Component;
import org.springframework.web.context.annotation.RequestScope;
@Component
@RequestScope
@RequiredArgsConstructor
public class AuditLogger {
private final JaxRsDpsLog logger;
private final DpsHeaders headers;
private AuditEvents events = null;
private AuditEvents getAuditEvents() {
if (this.events == null) {
this.events = new AuditEvents(this.headers.getUserEmail());
}
return this.events;
}
public void createdPartitionSuccess(List<String> resources) {
writeLog(getAuditEvents().getCreatePartitionEvent(AuditStatus.SUCCESS, resources));
}
public void createdPartitionFailure(List<String> resources) {
writeLog(getAuditEvents().getCreatePartitionEvent(AuditStatus.FAILURE, resources));
}
public void readPartitionSuccess(List<String> resources) {
writeLog(getAuditEvents().getReadPartitionEvent(AuditStatus.SUCCESS, resources));
}
public void readPartitionFailure(List<String> resources) {
writeLog(getAuditEvents().getReadPartitionEvent(AuditStatus.FAILURE, resources));
}
public void deletedPartitionSuccess(List<String> resources) {
writeLog(getAuditEvents().getDeletePartitionEvent(AuditStatus.SUCCESS, resources));
}
public void deletedPartitionFailure(List<String> resources) {
writeLog(getAuditEvents().getDeletePartitionEvent(AuditStatus.FAILURE, resources));
}
public void readServiceLivenessSuccess(List<String> resources) {
writeLog(getAuditEvents().getReadServiceLivenessEvent(AuditStatus.SUCCESS, resources));
}
public void readServiceLivenessFailure(List<String> resources) {
writeLog(getAuditEvents().getReadServiceLivenessEvent(AuditStatus.FAILURE, resources));
}
public void updatedPartitionSecretSuccess(List<String> resources) {
writeLog(getAuditEvents().getUpdatePartitionSecretEvent(AuditStatus.SUCCESS, resources));
}
public void updatedPartitionSecretFailure(List<String> resources) {
writeLog(getAuditEvents().getUpdatePartitionSecretEvent(AuditStatus.FAILURE, resources));
}
public void readListPartitionSuccess(List<String> resources) {
writeLog(getAuditEvents().getListPartitionEvent(AuditStatus.SUCCESS, resources));
}
public void readListPartitionFailure(List<String> resources) {
writeLog(getAuditEvents().getListPartitionEvent(AuditStatus.FAILURE, resources));
}
private void writeLog(AuditPayload log) {
this.logger.audit(log);
}
}
\ No newline at end of file
......@@ -14,19 +14,24 @@
package org.opengroup.osdu.partition.api;
import org.junit.Before;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import org.opengroup.osdu.partition.logging.AuditLogger;
import org.springframework.http.HttpStatus;
import static org.junit.jupiter.api.Assertions.*;
@RunWith(MockitoJUnitRunner.class)
public class HealthCheckTest {
private HealthCheck sut;
@Before
public void setup() {
this.sut = new HealthCheck();
}
@Mock
private AuditLogger auditLogger;
@InjectMocks
private HealthCheck sut;
@Test
public void should_returnHttp200_when_checkLiveness() {
......
......@@ -14,12 +14,24 @@
package org.opengroup.osdu.partition.api;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import static org.powermock.api.mockito.PowerMockito.mockStatic;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import org.opengroup.osdu.core.common.model.http.AppException;
import org.opengroup.osdu.partition.logging.AuditLogger;
import org.opengroup.osdu.partition.model.PartitionInfo;
import org.opengroup.osdu.partition.model.Property;
import org.opengroup.osdu.partition.provider.interfaces.IPartitionService;
......@@ -28,22 +40,8 @@ import org.powermock.modules.junit4.PowerMockRunner;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
import javax.servlet.http.HttpServletRequest;
import java.net.URI;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static org.junit.Assert.*;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.*;
import static org.powermock.api.mockito.PowerMockito.mockStatic;
@RunWith(PowerMockRunner.class)
@PrepareForTest(ServletUriComponentsBuilder.class)
public class PartitionApiTest {
......@@ -55,6 +53,9 @@ public class PartitionApiTest {
@Mock
private IPartitionService partitionService;
@Mock
private AuditLogger auditLogger;
@InjectMocks
private PartitionApi sut;
......
......@@ -19,6 +19,7 @@ package org.opengroup.osdu.partition.provider.gcp.service;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
......@@ -27,6 +28,7 @@ import lombok.RequiredArgsConstructor;
import org.apache.http.HttpStatus;
import org.opengroup.osdu.core.common.model.http.AppException;
import org.opengroup.osdu.core.common.provider.interfaces.IKmsClient;
import org.opengroup.osdu.partition.logging.AuditLogger;
import org.opengroup.osdu.partition.model.PartitionInfo;
import org.opengroup.osdu.partition.model.Property;
import org.opengroup.osdu.partition.provider.gcp.model.PartitionPropertyEntity;
......@@ -46,9 +48,12 @@ public class PartitionServiceImpl implements IPartitionService {
private final IKmsClient kmsClient;
private final AuditLogger auditLogger;
@Override
public PartitionInfo createPartition(String partitionId, PartitionInfo partitionInfo) {
if (this.partitionPropertyEntityRepository.findByPartitionId(partitionId).isPresent()) {
this.auditLogger.createdPartitionFailure(Collections.singletonList(partitionId));
throw new AppException(HttpStatus.SC_CONFLICT, UNKNOWN_ERROR_REASON,
"Partition already exists.");
}
......@@ -81,11 +86,13 @@ public class PartitionServiceImpl implements IPartitionService {
@Override
public PartitionInfo updatePartition(String partitionId, PartitionInfo partitionInfo) {
if (partitionInfo.getProperties().containsKey("id")) {
this.auditLogger.updatedPartitionSecretFailure(Collections.singletonList(partitionId));
throw new AppException(HttpStatus.SC_BAD_REQUEST, "can not update id",
"the field id can not be updated");
}
if (!this.partitionPropertyEntityRepository.findByPartitionId(partitionId).isPresent()) {
this.auditLogger.updatedPartitionSecretFailure(Collections.singletonList(partitionId));
throw new AppException(HttpStatus.SC_NOT_FOUND, UNKNOWN_ERROR_REASON,
"An attempt to update not existing partition.");
}
......@@ -120,11 +127,13 @@ public class PartitionServiceImpl implements IPartitionService {
}
private PartitionInfo getEncryptedPartition(String partitionId) {
if (!this.partitionPropertyEntityRepository.findByPartitionId(partitionId).isPresent()) {
this.auditLogger.readPartitionFailure(Collections.singletonList(partitionId));
throw new AppException(HttpStatus.SC_NOT_FOUND, UNKNOWN_ERROR_REASON,
"Partition does not exist.");
}
List<PartitionPropertyEntity> partitionPropertiesList = this.partitionPropertyEntityRepository
.findByPartitionId(partitionId)
.orElseThrow(
() -> new AppException(HttpStatus.SC_NOT_FOUND, UNKNOWN_ERROR_REASON,
"Partition does not exist."));
.findByPartitionId(partitionId).get();
PartitionInfo partitionInfo = new PartitionInfo();
Map<String, Property> partitionInfoProperties = new HashMap<>();
for (PartitionPropertyEntity entity : partitionPropertiesList) {
......@@ -152,6 +161,7 @@ public class PartitionServiceImpl implements IPartitionService {
@Override
public boolean deletePartition(String partitionId) {
if (!this.partitionPropertyEntityRepository.findByPartitionId(partitionId).isPresent()) {
this.auditLogger.deletedPartitionFailure(Collections.singletonList(partitionId));
throw new AppException(HttpStatus.SC_NOT_FOUND, UNKNOWN_ERROR_REASON,
"An attempt to delete not existing partition.");
}
......
......@@ -33,6 +33,7 @@ import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import org.opengroup.osdu.core.common.model.http.AppException;
import org.opengroup.osdu.partition.logging.AuditLogger;
import org.opengroup.osdu.partition.model.PartitionInfo;
import org.opengroup.osdu.partition.model.Property;
import org.opengroup.osdu.partition.provider.gcp.model.PartitionPropertyEntity;
......@@ -50,6 +51,9 @@ public class PartitionServiceImplTest {
@Mock
private PartitionPropertyEntityRepository partitionPropertyEntityRepository;
@Mock
private AuditLogger auditLogger;
@InjectMocks
private PartitionServiceImpl partitionServiceImpl;
......
......@@ -58,6 +58,7 @@ public abstract class TestUtils {
throws Exception {
Map<String, String> headers = getOsduTenantHeaders();
headers.put("user", "test_user@gmail.com");
return send(path, httpMethod, token, requestBody, query, headers, enforceHttp);
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment