/*
* The contents of this file are subject to the terms of the Common Development and
* Distribution License (the License). You may not use this file except in compliance with the
* License.
*
* You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
* specific language governing permission and limitations under the License.
*
* When distributing Covered Software, include this CDDL Header Notice in each file and include
* the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
* Header, with the fields enclosed by brackets [] replaced by your own identifying
* information: "Portions copyright [year] [name of copyright owner]".
*
* Copyright 2015 ForgeRock AS.
*/
package org.forgerock.openidm.audit.util;
import static org.assertj.core.api.Assertions.assertThat;
import static org.forgerock.json.JsonValue.array;
import static org.forgerock.json.JsonValue.field;
import static org.forgerock.json.JsonValue.json;
import static org.forgerock.json.JsonValue.object;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import org.forgerock.json.JsonValue;
import org.forgerock.json.resource.ActionRequest;
import org.forgerock.json.resource.ActionResponse;
import org.forgerock.json.resource.Connection;
import org.forgerock.json.resource.ConnectionFactory;
import org.forgerock.json.resource.CreateRequest;
import org.forgerock.json.resource.Request;
import org.forgerock.json.resource.RequestType;
import org.forgerock.json.resource.Requests;
import org.forgerock.json.resource.ResourceResponse;
import org.forgerock.json.resource.Responses;
import org.forgerock.openidm.core.IdentityServer;
import org.forgerock.openidm.core.PropertyAccessor;
import org.forgerock.services.TransactionId;
import org.forgerock.services.context.Context;
import org.forgerock.services.context.RootContext;
import org.forgerock.services.context.SecurityContext;
import org.forgerock.services.context.TransactionIdContext;
import org.mockito.ArgumentCaptor;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
/**
* Tests Router Activity Logger
*
* @see RouterActivityLogger
*/
public class RouterActivityLoggerTest {
public static final String TEST_MESSAGE = "test message";
public static final String TEST_OBJECT_ID = "test_object_id";
public static final String AUTHENTICATION_ID = "principal";
private Context context;
private JsonValue before;
private Request request;
private JsonValue after;
@BeforeClass
public void setup() throws Exception {
context =
new TransactionIdContext(
new SecurityContext(
new RootContext("test_id"), AUTHENTICATION_ID, null),
new TransactionId());
before = json(object(
field(ResourceResponse.FIELD_CONTENT_REVISION, "1"),
field("test", "oldValue")
));
request = Requests.newReadRequest("/bla/testPath");
after = json(object(
field(ResourceResponse.FIELD_CONTENT_REVISION, "2"),
field("test", "newValue")
));
}
@Test
public void testRootActivityLoggerWithBeforeAndAfter() throws Exception {
ConnectionFactory connectionFactory = mock(ConnectionFactory.class);
Connection connection = mock(Connection.class);
when(connectionFactory.getConnection()).thenReturn(connection);
when(connection.create(any(Context.class), any(CreateRequest.class))).thenReturn(
Responses.newResourceResponse("ba", "1", null));
ActionResponse actionResponse = Responses.newActionResponse(json(array("test")));
when(connection.action(any(Context.class), any(ActionRequest.class))).thenReturn(actionResponse);
ArgumentCaptor<CreateRequest> createRequestArgumentCaptor = ArgumentCaptor.forClass(CreateRequest.class);
// when
RouterActivityLogger activityLogger = new RouterActivityLogger(connectionFactory);
activityLogger.log(context, request, TEST_MESSAGE, TEST_OBJECT_ID, before, after, Status.SUCCESS);
// then
verify(connection).create(any(Context.class), createRequestArgumentCaptor.capture());
JsonValue content = createRequestArgumentCaptor.getValue().getContent();
String capturedEventName = content.get(OpenIDMActivityAuditEventBuilder.EVENT_NAME).asString();
assertThat(capturedEventName).isEqualTo(RouterActivityLogger.ACTIVITY_EVENT_NAME);
String capturedRevision = content.get(OpenIDMActivityAuditEventBuilder.REVISION).asString();
assertThat(capturedRevision).isEqualTo("2");
String capturedMessage = content.get(OpenIDMActivityAuditEventBuilder.MESSAGE).asString();
assertThat(capturedMessage).isEqualTo(TEST_MESSAGE);
Status status = content.get(OpenIDMActivityAuditEventBuilder.STATUS).asEnum(Status.class);
assertThat(status).isEqualTo(Status.SUCCESS);
String runAs = content.get(OpenIDMActivityAuditEventBuilder.RUN_AS).asString();
assertThat(runAs).isEqualTo(AUTHENTICATION_ID);
RequestType requestType = request.getRequestType();
assertThat(requestType).isEqualTo(RequestType.READ);
JsonValue capturedAfter = content.get(OpenIDMActivityAuditEventBuilder.AFTER);
assertThat(capturedAfter.isNull()).isTrue();
JsonValue capturedBefore = content.get(OpenIDMActivityAuditEventBuilder.BEFORE);
assertThat(capturedBefore.isNull()).isTrue();
}
@Test
public void testRootActivityLoggerWithNullBeforeAndAfter() throws Exception {
ConnectionFactory connectionFactory = mock(ConnectionFactory.class);
Connection connection = mock(Connection.class);
when(connectionFactory.getConnection()).thenReturn(connection);
when(connection.create(any(Context.class), any(CreateRequest.class))).thenReturn(
Responses.newResourceResponse("ba", "1", null));
ActionResponse actionResponse = Responses.newActionResponse(json(array("test")));
when(connection.action(any(Context.class), any(ActionRequest.class))).thenReturn(actionResponse);
ArgumentCaptor<CreateRequest> createRequestArgumentCaptor = ArgumentCaptor.forClass(CreateRequest.class);
// when
RouterActivityLogger activityLogger = new RouterActivityLogger(connectionFactory);
activityLogger.log(context, request, TEST_MESSAGE, TEST_OBJECT_ID, null, after, Status.SUCCESS);
// then
verify(connection).create(any(Context.class), createRequestArgumentCaptor.capture());
JsonValue content = createRequestArgumentCaptor.getValue().getContent();
String capturedEventName = content.get(OpenIDMActivityAuditEventBuilder.EVENT_NAME).asString();
assertThat(capturedEventName).isEqualTo(RouterActivityLogger.ACTIVITY_EVENT_NAME);
String capturedRevision = content.get(OpenIDMActivityAuditEventBuilder.REVISION).asString();
assertThat(capturedRevision).isEqualTo("2");
String capturedMessage = content.get(OpenIDMActivityAuditEventBuilder.MESSAGE).asString();
assertThat(capturedMessage).isEqualTo(TEST_MESSAGE);
}
@Test
public void testRootActivityLoggerWithBeforeAndNullAfter() throws Exception {
ConnectionFactory connectionFactory = mock(ConnectionFactory.class);
Connection connection = mock(Connection.class);
when(connectionFactory.getConnection()).thenReturn(connection);
when(connection.create(any(Context.class), any(CreateRequest.class))).thenReturn(
Responses.newResourceResponse("ba", "1", null));
ActionResponse actionResponse = Responses.newActionResponse(json(array("test")));
when(connection.action(any(Context.class), any(ActionRequest.class))).thenReturn(actionResponse);
ArgumentCaptor<CreateRequest> createRequestArgumentCaptor = ArgumentCaptor.forClass(CreateRequest.class);
// when
RouterActivityLogger activityLogger = new RouterActivityLogger(connectionFactory);
activityLogger.log(context, request, TEST_MESSAGE, TEST_OBJECT_ID, before, null, Status.SUCCESS);
// then
verify(connection).create(any(Context.class), createRequestArgumentCaptor.capture());
JsonValue content = createRequestArgumentCaptor.getValue().getContent();
String capturedEventName = content.get(OpenIDMActivityAuditEventBuilder.EVENT_NAME).asString();
assertThat(capturedEventName).isEqualTo(RouterActivityLogger.ACTIVITY_EVENT_NAME);
// 1 is expected since the revision should come from the 'before'
String capturedRevision = content.get(OpenIDMActivityAuditEventBuilder.REVISION).asString();
assertThat(capturedRevision).isEqualTo("1");
String capturedMessage = content.get(OpenIDMActivityAuditEventBuilder.MESSAGE).asString();
assertThat(capturedMessage).isEqualTo(TEST_MESSAGE);
}
@Test
public void testRootActivityLoggerWithLogFullObjectsOn() throws Exception {
ConnectionFactory connectionFactory = mock(ConnectionFactory.class);
Connection connection = mock(Connection.class);
when(connectionFactory.getConnection()).thenReturn(connection);
when(connection.create(any(Context.class), any(CreateRequest.class))).thenReturn(
Responses.newResourceResponse("ba", "1", null));
ActionResponse actionResponse = Responses.newActionResponse(json(array("test")));
when(connection.action(any(Context.class), any(ActionRequest.class))).thenReturn(actionResponse);
ArgumentCaptor<CreateRequest> createRequestArgumentCaptor = ArgumentCaptor.forClass(CreateRequest.class);
// given
IdentityServer.initInstance(new PropertyAccessor() {
@Override
public <T> T getProperty(String key, T defaultValue, Class<T> expected) {
if (key.equals(RouterActivityLogger.OPENIDM_AUDIT_LOG_FULL_OBJECTS)) {
return (T) "true";
}
return defaultValue;
}
});
// when
RouterActivityLogger activityLogger = new RouterActivityLogger(connectionFactory);
activityLogger.log(context, request, TEST_MESSAGE, TEST_OBJECT_ID, before, after, Status.SUCCESS);
// then
verify(connection).create(any(Context.class), createRequestArgumentCaptor.capture());
JsonValue content = createRequestArgumentCaptor.getValue().getContent();
JsonValue capturedAfter = content.get(OpenIDMActivityAuditEventBuilder.AFTER);
String rev = capturedAfter.get(ResourceResponse.FIELD_CONTENT_REVISION).asString();
assertThat(rev).isEqualTo("2");
}
}