Commit 0c6d4783 authored by Rostislav Dublin (EPAM)'s avatar Rostislav Dublin (EPAM)
Browse files

Merge branch 'gcp-audit-impl' into 'master'

Dataset: Audit Logs Implementation (GONRG-1762)

See merge request !92
parents a66a9ebc 9aa45e9e
Pipeline #34504 passed with stages
in 39 minutes and 22 seconds
......@@ -15,6 +15,7 @@
package org.opengroup.osdu.dataset.api;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.inject.Inject;
......@@ -22,6 +23,7 @@ import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import org.opengroup.osdu.core.common.model.http.DpsHeaders;
import org.opengroup.osdu.dataset.logging.AuditLogger;
import org.opengroup.osdu.dataset.model.request.DeliveryRole;
import org.opengroup.osdu.dataset.model.request.GetDatasetRegistryRequest;
import org.opengroup.osdu.dataset.model.response.GetDatasetStorageInstructionsResponse;
......@@ -50,13 +52,17 @@ public class DatasetDmsApi {
@Inject
private DatasetDmsService datasetDmsService;
@Inject
private AuditLogger auditLogger;
@GetMapping("/getStorageInstructions")
@PreAuthorize("@authorizationFilter.hasRole('" + DeliveryRole.VIEWER + "')")
public ResponseEntity<GetDatasetStorageInstructionsResponse> getStorageInstructions(
@RequestParam(value = "kindSubType") String kindSubType) {
GetDatasetStorageInstructionsResponse response = this.datasetDmsService.getStorageInstructions(kindSubType);
GetDatasetStorageInstructionsResponse response = this.datasetDmsService.getStorageInstructions(kindSubType);
this.auditLogger.readStorageInstructionsSuccess(Collections.singletonList(response.toString()));
return new ResponseEntity<GetDatasetStorageInstructionsResponse>(response, HttpStatus.OK);
}
......@@ -68,7 +74,8 @@ public class DatasetDmsApi {
List<String> datasetRegistryIds = new ArrayList<>();
datasetRegistryIds.add(datasetRegistryId);
Object response = this.datasetDmsService.getDatasetRetrievalInstructions(datasetRegistryIds);
Object response = this.datasetDmsService.getDatasetRetrievalInstructions(datasetRegistryIds);
this.auditLogger.readRetrievalInstructionsSuccess(Collections.singletonList(response.toString()));
return new ResponseEntity<Object>(response, HttpStatus.OK);
}
......@@ -77,7 +84,8 @@ public class DatasetDmsApi {
public ResponseEntity<Object> getRetrievalInstructions(
@RequestBody @Valid @NotNull GetDatasetRegistryRequest request) {
Object response = this.datasetDmsService.getDatasetRetrievalInstructions(request.datasetRegistryIds);
Object response = this.datasetDmsService.getDatasetRetrievalInstructions(request.datasetRegistryIds);
this.auditLogger.readRetrievalInstructionsSuccess(Collections.singletonList(response.toString()));
return new ResponseEntity<Object>(response, HttpStatus.OK);
}
......
......@@ -15,6 +15,7 @@
package org.opengroup.osdu.dataset.api;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.inject.Inject;
......@@ -23,6 +24,7 @@ import javax.validation.constraints.NotNull;
import org.opengroup.osdu.core.common.model.http.DpsHeaders;
import org.opengroup.osdu.core.common.model.storage.StorageRole;
import org.opengroup.osdu.dataset.logging.AuditLogger;
import org.opengroup.osdu.dataset.model.request.CreateDatasetRegistryRequest;
import org.opengroup.osdu.dataset.model.request.GetDatasetRegistryRequest;
import org.opengroup.osdu.dataset.model.response.GetCreateUpdateDatasetRegistryResponse;
......@@ -53,12 +55,16 @@ public class DatasetRegistryApi {
@Inject
private DatasetRegistryService dataRegistryService;
@Inject
private AuditLogger auditLogger;
@PutMapping("/registerDataset")
@PreAuthorize("@authorizationFilter.hasRole('" + StorageRole.CREATOR + "', '" + StorageRole.ADMIN + "')")
public ResponseEntity<GetCreateUpdateDatasetRegistryResponse> createOrUpdateDatasetRegistry(
@RequestBody @Valid @NotNull CreateDatasetRegistryRequest request) {
GetCreateUpdateDatasetRegistryResponse response = this.dataRegistryService.createOrUpdateDatasetRegistry(request.datasetRegistries);
GetCreateUpdateDatasetRegistryResponse response = this.dataRegistryService.createOrUpdateDatasetRegistry(request.datasetRegistries);
this.auditLogger.registerDatasetSuccess(Collections.singletonList(response.toString()));
return new ResponseEntity<GetCreateUpdateDatasetRegistryResponse>(response, HttpStatus.CREATED);
}
......@@ -70,7 +76,8 @@ public class DatasetRegistryApi {
List<String> datasetRegistryIds = new ArrayList<>();
datasetRegistryIds.add(datasetRegistryId);
GetCreateUpdateDatasetRegistryResponse response = this.dataRegistryService.getDatasetRegistries(datasetRegistryIds);
GetCreateUpdateDatasetRegistryResponse response = this.dataRegistryService.getDatasetRegistries(datasetRegistryIds);
this.auditLogger.readDatasetRegistriesSuccess(Collections.singletonList(response.toString()));
return new ResponseEntity<GetCreateUpdateDatasetRegistryResponse>(response, HttpStatus.OK);
}
......@@ -78,7 +85,8 @@ public class DatasetRegistryApi {
@PreAuthorize("@authorizationFilter.hasRole('" + StorageRole.CREATOR + "', '" + StorageRole.ADMIN + "', '" + StorageRole.VIEWER + "')")
public ResponseEntity<GetCreateUpdateDatasetRegistryResponse> getDatasetRegistry(
@RequestBody @Valid @NotNull GetDatasetRegistryRequest request) {
GetCreateUpdateDatasetRegistryResponse response = this.dataRegistryService.getDatasetRegistries(request.datasetRegistryIds);
GetCreateUpdateDatasetRegistryResponse response = this.dataRegistryService.getDatasetRegistries(request.datasetRegistryIds);
this.auditLogger.readDatasetRegistriesSuccess(Collections.singletonList(response.toString()));
return new ResponseEntity<GetCreateUpdateDatasetRegistryResponse>(response, HttpStatus.OK);
}
}
\ No newline at end of file
/*
* Copyright 2021 Google LLC
* Copyright 2021 EPAM Systems, Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.opengroup.osdu.dataset.logging;
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 READ_STORAGE_INSTRUCTIONS_ACTION_ID = "DS001";
private static final String READ_STORAGE_INSTRUCTIONS_MESSAGE = "Read storage instructions";
private static final String READ_RETRIEVAL_INSTRUCTIONS_ACTION_ID = "DS002";
private static final String READ_RETRIEVAL_INSTRUCTIONS_MESSAGE = "Read retrieval instructions";
private static final String REGISTER_DATASET_ACTION_ID = "DS003";
private static final String REGISTER_DATASET_MESSAGE = "Registered dataset";
private static final String READ_DATASET_REGISTRIES_ACTION_ID = "DS004";
private static final String READ_DATASET_REGISTRIES_MESSAGE = "Read dataset registries";
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 getReadStorageInstructionsEvent(AuditStatus status, List<String> resources) {
return AuditPayload.builder()
.action(AuditAction.READ)
.status(status)
.user(this.user)
.actionId(READ_STORAGE_INSTRUCTIONS_ACTION_ID)
.message(getStatusMessage(status, READ_STORAGE_INSTRUCTIONS_MESSAGE))
.resources(resources)
.build();
}
public AuditPayload getReadRetrievalInstructionsEvent(AuditStatus status,
List<String> resources) {
return AuditPayload.builder()
.action(AuditAction.READ)
.status(status)
.user(this.user)
.actionId(READ_RETRIEVAL_INSTRUCTIONS_ACTION_ID)
.message(getStatusMessage(status, READ_RETRIEVAL_INSTRUCTIONS_MESSAGE))
.resources(resources)
.build();
}
public AuditPayload getRegisterDatasetEvent(AuditStatus status, List<String> resources) {
return AuditPayload.builder()
.action(AuditAction.CREATE)
.status(status)
.user(this.user)
.actionId(REGISTER_DATASET_ACTION_ID)
.message(getStatusMessage(status, REGISTER_DATASET_MESSAGE))
.resources(resources)
.build();
}
public AuditPayload getReadDatasetRegistriesEvent(AuditStatus status, List<String> resources) {
return AuditPayload.builder()
.action(AuditAction.READ)
.status(status)
.user(this.user)
.actionId(READ_DATASET_REGISTRIES_ACTION_ID)
.message(getStatusMessage(status, READ_DATASET_REGISTRIES_MESSAGE))
.resources(resources)
.build();
}
private String getStatusMessage(AuditStatus status, String message) {
return String.format("%s - %s", message, status.name().toLowerCase());
}
}
\ No newline at end of file
/*
* Copyright 2021 Google LLC
* Copyright 2021 EPAM Systems, Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.opengroup.osdu.dataset.logging;
import java.util.List;
import java.util.Objects;
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 dpsHeaders;
private AuditEvents auditEvents;
private AuditEvents getAuditEvents() {
if (Objects.isNull(this.auditEvents)) {
this.auditEvents = new AuditEvents(this.dpsHeaders.getUserEmail());
}
return this.auditEvents;
}
public void readStorageInstructionsSuccess(List<String> resources) {
writeLog(getAuditEvents().getReadStorageInstructionsEvent(AuditStatus.SUCCESS, resources));
}
public void readStorageInstructionsFailure(List<String> resources) {
writeLog(getAuditEvents().getReadStorageInstructionsEvent(AuditStatus.FAILURE, resources));
}
public void readRetrievalInstructionsSuccess(List<String> resources) {
writeLog(getAuditEvents().getReadRetrievalInstructionsEvent(AuditStatus.SUCCESS, resources));
}
public void readRetrievalInstructionsFailure(List<String> resources) {
writeLog(getAuditEvents().getReadRetrievalInstructionsEvent(AuditStatus.FAILURE, resources));
}
public void registerDatasetSuccess(List<String> resources) {
writeLog(getAuditEvents().getRegisterDatasetEvent(AuditStatus.SUCCESS, resources));
}
public void registerDatasetFailure(List<String> resources) {
writeLog(getAuditEvents().getRegisterDatasetEvent(AuditStatus.FAILURE, resources));
}
public void readDatasetRegistriesSuccess(List<String> resources) {
writeLog(getAuditEvents().getReadDatasetRegistriesEvent(AuditStatus.SUCCESS, resources));
}
public void readDatasetRegistriesFailure(List<String> resources) {
writeLog(getAuditEvents().getReadDatasetRegistriesEvent(AuditStatus.FAILURE, resources));
}
private void writeLog(AuditPayload log) {
this.logger.audit(log);
}
}
\ No newline at end of file
......@@ -32,6 +32,7 @@ import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.opengroup.osdu.core.common.model.http.DpsHeaders;
import org.opengroup.osdu.core.common.model.tenant.TenantInfo;
import org.opengroup.osdu.dataset.logging.AuditLogger;
import org.opengroup.osdu.dataset.model.request.DeliveryRole;
import org.opengroup.osdu.dataset.model.response.DatasetRetrievalDeliveryItem;
import org.opengroup.osdu.dataset.model.response.GetDatasetStorageInstructionsResponse;
......@@ -51,6 +52,9 @@ public class DatasetDmsApiTest {
@Mock
private DatasetDmsService datasetDmsService;
@Mock
private AuditLogger auditLogger;
@InjectMocks
private DatasetDmsApi datasetDmsApi;
......
......@@ -37,6 +37,7 @@ import org.opengroup.osdu.core.common.model.storage.Record;
import org.opengroup.osdu.core.common.model.storage.StorageRole;
import org.opengroup.osdu.core.common.model.http.DpsHeaders;
import org.opengroup.osdu.core.common.model.tenant.TenantInfo;
import org.opengroup.osdu.dataset.logging.AuditLogger;
import org.opengroup.osdu.dataset.model.request.CreateDatasetRegistryRequest;
import org.opengroup.osdu.dataset.model.request.GetDatasetRegistryRequest;
import org.opengroup.osdu.dataset.model.response.GetCreateUpdateDatasetRegistryResponse;
......@@ -57,6 +58,9 @@ public class DatasetRegistryApiTest {
@Mock
private DpsHeaders httpHeaders;
@Mock
private AuditLogger auditLogger;
@InjectMocks
private DatasetRegistryApi datasetRegistryApi;
......
/*
* Copyright 2021 Google LLC
* Copyright 2021 EPAM Systems, Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.opengroup.osdu.dataset.logging;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.util.Collections;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.opengroup.osdu.core.common.logging.JaxRsDpsLog;
import org.opengroup.osdu.core.common.model.http.DpsHeaders;
@RunWith(MockitoJUnitRunner.class)
public class AuditLoggerTest {
@Mock
private JaxRsDpsLog log;
@Mock
private DpsHeaders dpsHeaders;
@InjectMocks
private AuditLogger sut;
private List<String> resources;
@Before
public void setup() {
when(this.dpsHeaders.getUserEmail()).thenReturn("test_user@email.com");
resources = Collections.singletonList("resources");
}
@Test
public void should_writeReadStorageInstructionsSuccessEvent() {
this.sut.readStorageInstructionsSuccess(this.resources);
verify(this.log, times(1)).audit(any());
}
@Test
public void should_writeReadStorageInstructionsFailureEvent() {
this.sut.readStorageInstructionsFailure(this.resources);
verify(this.log, times(1)).audit(any());
}
@Test
public void should_writeReadRetrievalInstructionsSuccessEvent() {
this.sut.readRetrievalInstructionsSuccess(this.resources);
verify(this.log, times(1)).audit(any());
}
@Test
public void should_writeReadRetrievalInstructionsFailureEvent() {
this.sut.readRetrievalInstructionsFailure(this.resources);
verify(this.log, times(1)).audit(any());
}
@Test
public void should_writeRegisterDatasetSuccessEvent() {
this.sut.registerDatasetSuccess(this.resources);
verify(this.log, times(1)).audit(any());
}
@Test
public void should_writeRegisterDatasetFailureEvent() {
this.sut.registerDatasetFailure(this.resources);
verify(this.log, times(1)).audit(any());
}
@Test
public void should_writeReadDatasetRegistriesSuccessEvent() {
this.sut.readDatasetRegistriesSuccess(this.resources);
verify(this.log, times(1)).audit(any());
}
@Test
public void should_writeReadDatasetRegistriesFailureEvent() {
this.sut.readDatasetRegistriesFailure(this.resources);
verify(this.log, times(1)).audit(any());
}
}
\ No newline at end of file
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