| | |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2013 ForgeRock AS |
| | | * Copyright 2013-2014 ForgeRock AS |
| | | */ |
| | | package org.opends.server.loggers; |
| | | |
| | | import static org.mockito.Mockito.*; |
| | | import static org.testng.Assert.*; |
| | | |
| | | |
| | | import static org.assertj.core.api.Assertions.assertThat; |
| | | import static org.mockito.Mockito.mock; |
| | | import static org.mockito.Mockito.when; |
| | | |
| | | import java.util.Arrays; |
| | | import java.util.SortedSet; |
| | | import java.util.TreeSet; |
| | | |
| | | import org.forgerock.opendj.ldap.AddressMask; |
| | | import org.forgerock.opendj.ldap.ResultCode; |
| | | import org.opends.server.DirectoryServerTestCase; |
| | | import org.opends.server.TestCaseUtils; |
| | | import org.opends.server.admin.std.meta.AccessLogFilteringCriteriaCfgDefn.LogRecordType; |
| | | import org.opends.server.admin.std.server.AccessLogFilteringCriteriaCfg; |
| | | import org.opends.server.api.ClientConnection; |
| | | import org.opends.server.core.DirectoryServer; |
| | | import org.opends.server.core.SearchOperation; |
| | | import org.opends.server.loggers.AbstractTextAccessLogPublisher.CriteriaFilter; |
| | | import org.opends.server.loggers.AbstractTextAccessLogPublisher.RootFilter; |
| | | import org.opends.server.types.AuthenticationInfo; |
| | | import org.opends.server.types.DN; |
| | | import org.opends.server.types.DirectoryException; |
| | | import org.opends.server.types.Operation; |
| | | import org.opends.server.types.OperationType; |
| | | import org.testng.annotations.AfterClass; |
| | | import org.testng.annotations.BeforeClass; |
| | | import org.testng.annotations.DataProvider; |
| | | import org.testng.annotations.Test; |
| | | |
| | | |
| | | |
| | | @SuppressWarnings("javadoc") |
| | | public class AbstractTextAccessLogPublisherTest extends DirectoryServerTestCase |
| | | { |
| | | |
| | | @AfterClass |
| | | public void afterClass() throws Exception |
| | | { |
| | | // Make sure group is removed from group manager. |
| | | TestCaseUtils.deleteEntry(dn("cn=group 1,ou=Groups,o=test")); |
| | | TestCaseUtils.clearDataBackends(); |
| | | } |
| | | |
| | | |
| | | |
| | | @BeforeClass |
| | | public void beforeClass() throws Exception |
| | | { |
| | | TestCaseUtils.startServer(); |
| | | TestCaseUtils.clearDataBackends(); |
| | | TestCaseUtils.initializeTestBackend(true); |
| | | TestCaseUtils.addEntries( |
| | | // @formatter:off |
| | | "dn: ou=People,o=test", |
| | | "objectClass: top", |
| | | "objectClass: organizationalUnit", |
| | | "ou: People", |
| | | "", |
| | | "dn: ou=Groups,o=test", |
| | | "objectClass: top", |
| | | "objectClass: organizationalUnit", |
| | | "ou: Groups", |
| | | "", |
| | | "dn: cn=group 1,ou=Groups,o=test", |
| | | "objectClass: top", |
| | | "objectClass: groupOfNames", |
| | | "cn: group 1", |
| | | "member: uid=user.1,ou=People,o=test", |
| | | "", |
| | | "dn: uid=user.1,ou=People,o=test", |
| | | "objectClass: top", |
| | | "objectClass: person", |
| | | "objectClass: organizationalPerson", |
| | | "objectClass: inetOrgPerson", |
| | | "uid: user.1", |
| | | "givenName: User", |
| | | "sn: 1", |
| | | "cn: User 1", |
| | | "userPassword: password", |
| | | "", |
| | | "dn: uid=user.2,ou=People,o=test", |
| | | "objectClass: top", |
| | | "objectClass: person", |
| | | "objectClass: organizationalPerson", |
| | | "objectClass: inetOrgPerson", |
| | | "uid: user.2", |
| | | "givenName: User", |
| | | "sn: 2", |
| | | "cn: User 2", |
| | | "userPassword: password"); |
| | | // @formatter:on |
| | | } |
| | | |
| | | |
| | | |
| | | @DataProvider(name = "isLoggableData") |
| | | public Object[][] getIsLoggableData() |
| | | private Object[][] getIsLoggableData() |
| | | { |
| | | // When suppress is set to true and the corresponding operation is set to |
| | | // true too, then the operation is not loggable. |
| | |
| | | // There is just one exception: when the operation is a synchronization |
| | | // operation and we do not suppress synchronization operation, then we |
| | | // return true regardless of whether this is an internal operation |
| | | // @formatter:off |
| | | return new Object[][] { |
| | | { true, true, true, true, false }, |
| | | { true, true, true, false, false }, |
| | |
| | | { false, false, true, false, true }, |
| | | { false, false, false, true, true }, |
| | | { false, false, false, false, true }, }; |
| | | // @formatter:on |
| | | } |
| | | |
| | | |
| | | |
| | | @Test(dataProvider = "isLoggableData") |
| | | public void rootFilterIsLoggable(boolean suppressSynchronization, |
| | | boolean isSynchronizationOp, boolean suppressInternal, |
| | | boolean isInternalOp, boolean expectedTestResult) |
| | | public void rootFilterIsLoggable(final boolean suppressSynchronization, |
| | | final boolean isSynchronizationOp, final boolean suppressInternal, |
| | | final boolean isInternalOp, final boolean expectedTestResult) |
| | | { |
| | | final Operation operation = mock(Operation.class); |
| | | when(operation.isSynchronizationOperation()) |
| | | .thenReturn(isSynchronizationOp); |
| | | when(operation.isInnerOperation()).thenReturn(isInternalOp); |
| | | |
| | | final RootFilter filter = |
| | | new RootFilter(suppressInternal, suppressSynchronization, null, null); |
| | | assertEquals(filter.isLoggable(operation), expectedTestResult); |
| | | final RootFilter filter = new RootFilter(suppressInternal, |
| | | suppressSynchronization, null, null); |
| | | assertThat(filter.isLoggable(operation)).isEqualTo(expectedTestResult); |
| | | } |
| | | |
| | | |
| | | |
| | | @Test |
| | | public void testCriteriaFilterDefault() throws Exception |
| | | { |
| | | final AccessLogFilteringCriteriaCfg cfg = mockCriteriaFilterCfg(); |
| | | final CriteriaFilter filter = new CriteriaFilter(cfg); |
| | | final Operation operation = mockAnonymousSearchOperation(); |
| | | assertThat(filter.isRequestLoggable(operation)).isTrue(); |
| | | } |
| | | |
| | | |
| | | |
| | | @Test |
| | | public void testCriteriaFilterRequestTargetDNEqualTo() throws Exception |
| | | { |
| | | final AccessLogFilteringCriteriaCfg cfg = mockCriteriaFilterCfg(); |
| | | when(cfg.getRequestTargetDNEqualTo()).thenReturn(setOf("dc=com")); |
| | | final CriteriaFilter filter = new CriteriaFilter(cfg); |
| | | final SearchOperation operation = mockAnonymousSearchOperation(); |
| | | when(operation.getBaseDN()).thenReturn(dn("dc=com"), dn("dc=org")); |
| | | assertThat(filter.isRequestLoggable(operation)).isTrue(); |
| | | assertThat(filter.isRequestLoggable(operation)).isFalse(); |
| | | } |
| | | |
| | | |
| | | |
| | | @Test |
| | | public void testCriteriaFilterRequestTargetDNNotEqualTo() throws Exception |
| | | { |
| | | final AccessLogFilteringCriteriaCfg cfg = mockCriteriaFilterCfg(); |
| | | when(cfg.getRequestTargetDNNotEqualTo()).thenReturn(setOf("dc=com")); |
| | | final CriteriaFilter filter = new CriteriaFilter(cfg); |
| | | final SearchOperation operation = mockAnonymousSearchOperation(); |
| | | when(operation.getBaseDN()).thenReturn(dn("dc=com"), dn("dc=org")); |
| | | assertThat(filter.isRequestLoggable(operation)).isFalse(); |
| | | assertThat(filter.isRequestLoggable(operation)).isTrue(); |
| | | } |
| | | |
| | | |
| | | |
| | | @Test |
| | | public void testCriteriaFilterResponseEtimeGreaterThan() throws Exception |
| | | { |
| | | final AccessLogFilteringCriteriaCfg cfg = mockCriteriaFilterCfg(); |
| | | when(cfg.getResponseEtimeGreaterThan()).thenReturn(100); |
| | | final CriteriaFilter filter = new CriteriaFilter(cfg); |
| | | final SearchOperation operation = mockAnonymousSearchOperation(); |
| | | when(operation.getProcessingTime()).thenReturn(50L, 150L); |
| | | assertThat(filter.isResponseLoggable(operation)).isFalse(); |
| | | assertThat(filter.isResponseLoggable(operation)).isTrue(); |
| | | } |
| | | |
| | | |
| | | |
| | | @Test |
| | | public void testCriteriaFilterResponseEtimeLessThan() throws Exception |
| | | { |
| | | final AccessLogFilteringCriteriaCfg cfg = mockCriteriaFilterCfg(); |
| | | when(cfg.getResponseEtimeLessThan()).thenReturn(100); |
| | | final CriteriaFilter filter = new CriteriaFilter(cfg); |
| | | final SearchOperation operation = mockAnonymousSearchOperation(); |
| | | when(operation.getProcessingTime()).thenReturn(50L, 150L); |
| | | assertThat(filter.isResponseLoggable(operation)).isTrue(); |
| | | assertThat(filter.isResponseLoggable(operation)).isFalse(); |
| | | } |
| | | |
| | | |
| | | |
| | | @Test |
| | | public void testCriteriaFilterResponseResultCodeEqualTo() throws Exception |
| | | { |
| | | final AccessLogFilteringCriteriaCfg cfg = mockCriteriaFilterCfg(); |
| | | when(cfg.getResponseResultCodeEqualTo()).thenReturn(setOf(32)); |
| | | final CriteriaFilter filter = new CriteriaFilter(cfg); |
| | | final SearchOperation operation = mockAnonymousSearchOperation(); |
| | | when(operation.getResultCode()).thenReturn(ResultCode.NO_SUCH_OBJECT, |
| | | ResultCode.SUCCESS); |
| | | assertThat(filter.isResponseLoggable(operation)).isTrue(); |
| | | assertThat(filter.isResponseLoggable(operation)).isFalse(); |
| | | } |
| | | |
| | | |
| | | |
| | | @Test |
| | | public void testCriteriaFilterResponseResultCodeNotEqualTo() throws Exception |
| | | { |
| | | final AccessLogFilteringCriteriaCfg cfg = mockCriteriaFilterCfg(); |
| | | when(cfg.getResponseResultCodeNotEqualTo()).thenReturn(setOf(32)); |
| | | final CriteriaFilter filter = new CriteriaFilter(cfg); |
| | | final SearchOperation operation = mockAnonymousSearchOperation(); |
| | | when(operation.getResultCode()).thenReturn(ResultCode.NO_SUCH_OBJECT, |
| | | ResultCode.SUCCESS); |
| | | assertThat(filter.isResponseLoggable(operation)).isFalse(); |
| | | assertThat(filter.isResponseLoggable(operation)).isTrue(); |
| | | } |
| | | |
| | | |
| | | |
| | | @Test |
| | | public void testCriteriaFilterUserDNEqualTo() throws Exception |
| | | { |
| | | final AccessLogFilteringCriteriaCfg cfg = mockCriteriaFilterCfg(); |
| | | when(cfg.getUserDNEqualTo()) |
| | | .thenReturn(setOf(dnOfUserInGroup().toString())); |
| | | final CriteriaFilter filter = new CriteriaFilter(cfg); |
| | | final SearchOperation operation1 = mockAuthenticatedSearchOperation(dnOfUserInGroup()); |
| | | assertThat(filter.isRequestLoggable(operation1)).isTrue(); |
| | | final SearchOperation operation2 = mockAuthenticatedSearchOperation(dnOfUserNotInGroup()); |
| | | assertThat(filter.isRequestLoggable(operation2)).isFalse(); |
| | | } |
| | | |
| | | |
| | | |
| | | @Test |
| | | public void testCriteriaFilterUserDNNotEqualTo() throws Exception |
| | | { |
| | | final AccessLogFilteringCriteriaCfg cfg = mockCriteriaFilterCfg(); |
| | | when(cfg.getUserDNNotEqualTo()).thenReturn( |
| | | setOf(dnOfUserInGroup().toString())); |
| | | final CriteriaFilter filter = new CriteriaFilter(cfg); |
| | | final SearchOperation operation1 = mockAuthenticatedSearchOperation(dnOfUserInGroup()); |
| | | assertThat(filter.isRequestLoggable(operation1)).isFalse(); |
| | | final SearchOperation operation2 = mockAuthenticatedSearchOperation(dnOfUserNotInGroup()); |
| | | assertThat(filter.isRequestLoggable(operation2)).isTrue(); |
| | | } |
| | | |
| | | |
| | | |
| | | @Test |
| | | public void testCriteriaFilterUserIsMemberOf() throws Exception |
| | | { |
| | | final AccessLogFilteringCriteriaCfg cfg = mockCriteriaFilterCfg(); |
| | | when(cfg.getUserIsMemberOf()).thenReturn(setOf(dnOfGroup())); |
| | | final CriteriaFilter filter = new CriteriaFilter(cfg); |
| | | final SearchOperation operation1 = mockAuthenticatedSearchOperation(dnOfUserInGroup()); |
| | | assertThat(filter.isRequestLoggable(operation1)).isTrue(); |
| | | final SearchOperation operation2 = mockAuthenticatedSearchOperation(dnOfUserNotInGroup()); |
| | | assertThat(filter.isRequestLoggable(operation2)).isFalse(); |
| | | } |
| | | |
| | | |
| | | |
| | | @Test |
| | | public void testCriteriaFilterUserIsNotMemberOf() throws Exception |
| | | { |
| | | final AccessLogFilteringCriteriaCfg cfg = mockCriteriaFilterCfg(); |
| | | when(cfg.getUserIsNotMemberOf()).thenReturn(setOf(dnOfGroup())); |
| | | final CriteriaFilter filter = new CriteriaFilter(cfg); |
| | | final SearchOperation operation1 = mockAuthenticatedSearchOperation(dnOfUserInGroup()); |
| | | assertThat(filter.isRequestLoggable(operation1)).isFalse(); |
| | | final SearchOperation operation2 = mockAuthenticatedSearchOperation(dnOfUserNotInGroup()); |
| | | assertThat(filter.isRequestLoggable(operation2)).isTrue(); |
| | | } |
| | | |
| | | |
| | | |
| | | private DN dn(final String dn) |
| | | { |
| | | try |
| | | { |
| | | return DN.valueOf(dn); |
| | | } |
| | | catch (final DirectoryException e) |
| | | { |
| | | throw new RuntimeException(e); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | private DN dnOfGroup() |
| | | { |
| | | return dn("cn=group 1,ou=Groups,o=test"); |
| | | } |
| | | |
| | | |
| | | |
| | | private DN dnOfUserInGroup() |
| | | { |
| | | return dn("uid=user.1,ou=People,o=test"); |
| | | } |
| | | |
| | | |
| | | |
| | | private DN dnOfUserNotInGroup() |
| | | { |
| | | return dn("uid=user.2,ou=People,o=test"); |
| | | } |
| | | |
| | | |
| | | |
| | | private SearchOperation mockAnonymousSearchOperation() throws Exception |
| | | { |
| | | return mockSearchOperation(new AuthenticationInfo()); |
| | | } |
| | | |
| | | |
| | | |
| | | private SearchOperation mockAuthenticatedSearchOperation(final DN user) |
| | | throws Exception |
| | | { |
| | | return mockSearchOperation(new AuthenticationInfo( |
| | | DirectoryServer.getEntry(user), false)); |
| | | } |
| | | |
| | | |
| | | |
| | | private AccessLogFilteringCriteriaCfg mockCriteriaFilterCfg() |
| | | { |
| | | final AccessLogFilteringCriteriaCfg cfg = mock(AccessLogFilteringCriteriaCfg.class); |
| | | when(cfg.getConnectionClientAddressEqualTo()).thenReturn( |
| | | new TreeSet<AddressMask>()); |
| | | when(cfg.getConnectionClientAddressNotEqualTo()).thenReturn( |
| | | new TreeSet<AddressMask>()); |
| | | when(cfg.getConnectionPortEqualTo()).thenReturn(new TreeSet<Integer>()); |
| | | when(cfg.getConnectionProtocolEqualTo()).thenReturn(new TreeSet<String>()); |
| | | when(cfg.getLogRecordType()).thenReturn(new TreeSet<LogRecordType>()); |
| | | when(cfg.getRequestTargetDNEqualTo()).thenReturn(new TreeSet<String>()); |
| | | when(cfg.getRequestTargetDNNotEqualTo()).thenReturn(new TreeSet<String>()); |
| | | when(cfg.getResponseEtimeGreaterThan()).thenReturn(null); |
| | | when(cfg.getResponseEtimeLessThan()).thenReturn(null); |
| | | when(cfg.getResponseResultCodeEqualTo()).thenReturn(new TreeSet<Integer>()); |
| | | when(cfg.getResponseResultCodeNotEqualTo()).thenReturn( |
| | | new TreeSet<Integer>()); |
| | | when(cfg.isSearchResponseIsIndexed()).thenReturn(null); |
| | | when(cfg.getSearchResponseNentriesGreaterThan()).thenReturn(null); |
| | | when(cfg.getSearchResponseNentriesLessThan()).thenReturn(null); |
| | | when(cfg.getUserDNEqualTo()).thenReturn(new TreeSet<String>()); |
| | | when(cfg.getUserDNNotEqualTo()).thenReturn(new TreeSet<String>()); |
| | | when(cfg.getUserIsMemberOf()).thenReturn(new TreeSet<DN>()); |
| | | when(cfg.getUserIsNotMemberOf()).thenReturn(new TreeSet<DN>()); |
| | | return cfg; |
| | | } |
| | | |
| | | |
| | | |
| | | private SearchOperation mockSearchOperation(final AuthenticationInfo authInfo) |
| | | throws Exception |
| | | { |
| | | final SearchOperation operation = mock(SearchOperation.class); |
| | | final ClientConnection connection = mock(ClientConnection.class); |
| | | when(operation.getOperationType()).thenReturn(OperationType.SEARCH); |
| | | when(operation.getClientConnection()).thenReturn(connection); |
| | | when(operation.getResultCode()).thenReturn(ResultCode.SUCCESS); |
| | | when(connection.getAuthenticationInfo()).thenReturn(authInfo); |
| | | return operation; |
| | | } |
| | | |
| | | |
| | | |
| | | private <T> SortedSet<T> setOf(final T... values) |
| | | { |
| | | return new TreeSet<T>(Arrays.asList(values)); |
| | | } |
| | | } |