package org.owasp.security.logging.filter;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
import org.owasp.security.logging.SecurityMarkers;
import org.slf4j.LoggerFactory;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.classic.spi.LoggingEvent;
import ch.qos.logback.core.Appender;
import ch.qos.logback.core.spi.FilterReply;
import org.junit.After;
import org.junit.Before;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import static org.mockito.Mockito.verify;
import org.mockito.Spy;
import org.mockito.runners.MockitoJUnitRunner;
import org.slf4j.Marker;
/**
*
* @author August Detlefsen [augustd@codemagi.com]
*/
@RunWith(MockitoJUnitRunner.class)
public class ExcludeClassifiedMarkerFilterTest {
LoggerContext loggerContext = (LoggerContext) LoggerFactory
.getILoggerFactory();
Logger LOGGER = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
@Spy
private final Appender<ILoggingEvent> mockAppender = LOGGER
.getAppender("NOT_CLASSIFIED_CONSOLE");
// Captor is genericised with ch.qos.logback.classic.spi.LoggingEvent
@Captor
private ArgumentCaptor<LoggingEvent> captorLoggingEvent;
@Before
public void setUp() {
LOGGER.addAppender(mockAppender);
}
@After
public void teardown() {
LOGGER.detachAppender(mockAppender);
}
@Test
public void testAppenderNormalEvent() {
LOGGER.info("This statement is NOT confidential");
// Now verify our logging interactions
verify(mockAppender).doAppend(captorLoggingEvent.capture());
// Get the logging event from the captor
LoggingEvent loggingEvent = captorLoggingEvent.getValue();
System.out.println("testAppender(): loggingEvent: " + loggingEvent);
// check the filter chain decision for this event
assertEquals(FilterReply.NEUTRAL,
mockAppender.getFilterChainDecision(loggingEvent));
}
@Test
public void testAppenderSecurityEvent() {
LOGGER.info(SecurityMarkers.SECURITY_SUCCESS,
"This statement is a security event");
// Now verify our logging interactions
verify(mockAppender).doAppend(captorLoggingEvent.capture());
// Get the logging event from the captor
LoggingEvent loggingEvent = captorLoggingEvent.getValue();
System.out.println("testAppender(): loggingEvent: " + loggingEvent);
// check the filter chain decision for this event
assertEquals(FilterReply.NEUTRAL,
mockAppender.getFilterChainDecision(loggingEvent));
}
@Test
public void testAppenderConfidentialEvent() {
LOGGER.info(SecurityMarkers.CONFIDENTIAL,
"This statement is confidential");
// Now verify our logging interactions
verify(mockAppender).doAppend(captorLoggingEvent.capture());
// Get the logging event from the captor
LoggingEvent loggingEvent = captorLoggingEvent.getValue();
System.out.println("testAppender(): loggingEvent: " + loggingEvent);
// check the filter chain decision for this event
assertEquals(FilterReply.DENY,
mockAppender.getFilterChainDecision(loggingEvent));
}
@Test
public void testAppenderRestrictedEvent() {
LOGGER.info(SecurityMarkers.RESTRICTED, "This statement is restricted");
// Now verify our logging interactions
verify(mockAppender).doAppend(captorLoggingEvent.capture());
// Get the logging event from the captor
LoggingEvent loggingEvent = captorLoggingEvent.getValue();
System.out.println("testAppender(): loggingEvent: " + loggingEvent);
// check the filter chain decision for this event
assertEquals(FilterReply.DENY,
mockAppender.getFilterChainDecision(loggingEvent));
}
@Test
public void testAppenderSecretEvent() {
LOGGER.info(SecurityMarkers.SECRET, "This statement is secret");
// Now verify our logging interactions
verify(mockAppender).doAppend(captorLoggingEvent.capture());
// Get the logging event from the captor
LoggingEvent loggingEvent = captorLoggingEvent.getValue();
System.out.println("testAppender(): loggingEvent: " + loggingEvent);
// check the filter chain decision for this event
assertEquals(FilterReply.DENY,
mockAppender.getFilterChainDecision(loggingEvent));
}
@Test
public void testAppenderTopSecretEvent() {
LOGGER.info(SecurityMarkers.TOP_SECRET, "This statement is top secret");
// Now verify our logging interactions
verify(mockAppender).doAppend(captorLoggingEvent.capture());
// Get the logging event from the captor
LoggingEvent loggingEvent = captorLoggingEvent.getValue();
System.out.println("testAppender(): loggingEvent: " + loggingEvent);
// check the filter chain decision for this event
assertEquals(FilterReply.DENY,
mockAppender.getFilterChainDecision(loggingEvent));
}
@Test
public void testAppenderMultipleEvent() {
Marker multi = SecurityMarkers.getMarker(
SecurityMarkers.SECURITY_AUDIT, SecurityMarkers.CONFIDENTIAL);
LOGGER.info(multi,
"This statement contains multiple markers: audit and confidential");
// Now verify our logging interactions
verify(mockAppender).doAppend(captorLoggingEvent.capture());
// Get the logging event from the captor
LoggingEvent loggingEvent = captorLoggingEvent.getValue();
System.out.println("testAppender(): loggingEvent: " + loggingEvent);
// check the filter chain decision for this event
assertEquals(FilterReply.DENY,
mockAppender.getFilterChainDecision(loggingEvent));
}
@Test
public void testRaw() {
// create a new marker filter
ExcludeClassifiedMarkerFilter mkt = new ExcludeClassifiedMarkerFilter();
mkt.setContext(loggerContext);
mkt.start();
assertTrue(mkt.isStarted());
// test a logging event with no markers
ILoggingEvent nulEvent = new LoggingEvent();
assertEquals(FilterReply.NEUTRAL, mkt.decide(nulEvent));
// test a logging event with the CONFIDENTIAL marker
LoggingEvent confidentialEvent = new LoggingEvent();
confidentialEvent.setMarker(SecurityMarkers.CONFIDENTIAL);
assertEquals(FilterReply.DENY, mkt.decide(confidentialEvent));
// test a logging event with the RESTRICTED marker
LoggingEvent restrictedEvent = new LoggingEvent();
restrictedEvent.setMarker(SecurityMarkers.RESTRICTED);
assertEquals(FilterReply.DENY, mkt.decide(restrictedEvent));
// test a logging event with the SECRET marker
LoggingEvent secretEvent = new LoggingEvent();
secretEvent.setMarker(SecurityMarkers.SECRET);
assertEquals(FilterReply.DENY, mkt.decide(secretEvent));
// test a logging event with the TOP_SECRET marker
LoggingEvent topSecretEvent = new LoggingEvent();
topSecretEvent.setMarker(SecurityMarkers.TOP_SECRET);
assertEquals(FilterReply.DENY, mkt.decide(topSecretEvent));
// test a logging event without the CONFIDENTIAL marker
LoggingEvent normalEvent = new LoggingEvent();
normalEvent.setMarker(SecurityMarkers.EVENT_SUCCESS);
assertEquals(FilterReply.NEUTRAL, mkt.decide(nulEvent));
}
}