package play.modules.logger; import org.junit.Before; import org.junit.Test; import play.Play; import play.data.parsing.UrlEncodedParser; import play.mvc.Http; import play.mvc.results.*; import play.rebel.RenderView; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.util.HashMap; import java.util.Properties; import static org.junit.Assert.*; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; public class RequestLogPluginTest { @SuppressWarnings("deprecation") Http.Request request = new Http.Request(); @Before public void setUp() { if (Play.configuration == null) Play.configuration = new Properties(); Play.configuration.setProperty("request.log.maskParams", "password|cvv|card.cvv|card.number"); new RequestLogPlugin().onConfigurationRead(); Http.Request.current.set(request); } @Test public void passwordIsMasked() { setQueryString("username=anton&password=123&password2=456&newPassword=678&password=789&oldPassword=1693&age=12"); String maskedParams = RequestLogPlugin.extractParams(request); assertTrue(maskedParams.contains("username=anton")); assertTrue(maskedParams.contains("age=12")); assertTrue(maskedParams.contains("password2=*")); assertTrue(maskedParams.contains("newPassword=*")); assertTrue(maskedParams.contains("oldPassword=*")); assertTrue(maskedParams.contains("password=*")); assertFalse(maskedParams.contains("123")); assertFalse(maskedParams.contains("456")); assertFalse(maskedParams.contains("67")); assertFalse(maskedParams.contains("789")); assertFalse(maskedParams.contains("1693")); } @Test public void cvvIsMasked() { setQueryString("card.holderName=Some+Body&card.number=6789690444552800&" + "card.validityMonth=07&card.validityYear=2015&card.cvv=907&cvv=600"); String maskedParams = RequestLogPlugin.extractParams(request); assertTrue(maskedParams.contains("card.validityYear=2015")); assertTrue(maskedParams.contains("card.validityMonth=07")); assertTrue(maskedParams.contains("card.holderName=Some Body")); assertTrue(maskedParams.contains("card.cvv=*")); assertTrue(maskedParams.contains("cvv=*")); assertTrue(maskedParams.contains("card.number=*")); assertFalse(maskedParams.contains("6789690444552800")); assertFalse(maskedParams.contains("907")); assertFalse(maskedParams.contains("600")); } @Test public void cardNumberIsMasked() { setQueryString("card.number=6789 6904 4455 2800"); assertEquals("card.number=*", RequestLogPlugin.extractParams(request)); } @Test public void postParametersAreIncluded() { setQueryString("id=123"); request.contentType = "application/x-www-form-urlencoded"; request.body = new ByteArrayInputStream("password=456&x=y".getBytes()); String maskedParams = RequestLogPlugin.extractParams(request); assertTrue(maskedParams.contains("id=123")); assertTrue(maskedParams.contains("password=*")); assertTrue(maskedParams.contains("x=y")); assertFalse(maskedParams.contains("456")); } @Test public void skipsPlaySpecificParameters() { setQueryString("authenticityToken=skip&action=skip&controller=skip&abc=value"); assertEquals("abc=value", RequestLogPlugin.extractParams(request)); } @Test public void paramsAreDecoded() { setQueryString("hello=A+B+%43"); assertEquals("hello=A B C", RequestLogPlugin.extractParams(request)); } @Test public void paramsAreSkipped_if_thereWasAnErrorWhenParsingRequestParams() { request.contentType = "application/json"; request.encoding = "erroneous"; assertEquals("", RequestLogPlugin.extractParams(request)); } @Test public void customLogData() { assertEquals("", RequestLogPlugin.getRequestLogCustomData(request)); request.args = new HashMap<>(); request.args.put("requestLogCustomData", "xtra"); assertEquals(" xtra", RequestLogPlugin.getRequestLogCustomData(request)); } @Test public void setsCurrentThreadName_by_actionName() { request.action = "Payments.history"; Thread.currentThread().setName("play-thread-666"); new RequestLogPlugin().beforeActionInvocation(null); assertEquals("play-thread-666 Payments.history", Thread.currentThread().getName()); } @Test public void ignoresPreviouslySetThreadName_if_itWasNotResetForWhateverReason() { request.action = "Payments.history"; Thread.currentThread().setName("play-thread-1 Bank.statement"); new RequestLogPlugin().beforeActionInvocation(null); assertEquals("play-thread-1 Payments.history", Thread.currentThread().getName()); } @Test public void resetsCurrentThreadName_after_actionInvocation() { Thread.currentThread().setName("play-thread-007 Payments.history"); new RequestLogPlugin().afterActionInvocation(); assertEquals("play-thread-007", Thread.currentThread().getName()); } @Test public void noResultMeansRenderingError() { assertEquals("RenderError", RequestLogPlugin.result(null)); } @Test public void logsRedirectUrl() { Redirect result = new Redirect("/foo"); assertEquals("Redirect /foo", RequestLogPlugin.result(result)); } @Test public void logsTemplateRenderingTime() { RenderTemplate result = mock(RenderTemplate.class); when(result.getRenderTime()).thenReturn(101L); when(result.getName()).thenReturn("Employees/registry.html"); assertEquals("RenderTemplate Employees/registry.html 101 ms", RequestLogPlugin.result(result)); } @Test public void logsViewRenderingTime() { RenderView result = mock(RenderView.class); when(result.getRenderTime()).thenReturn(101L); when(result.getName()).thenReturn("Employees/registry.html"); assertEquals("RenderView Employees/registry.html 101 ms", RequestLogPlugin.result(result)); } @Test public void logsFileName_forRenderBinary() { RenderBinary result = new RenderBinary((InputStream) null, "statement.dbf"); assertEquals("RenderBinary statement.dbf", RequestLogPlugin.result(result)); } @Test public void logsFileNameAndContentType_forRenderBinary() { RenderBinary result = new RenderBinary(null, "cert.pem", "application/pkix-cert", false); assertEquals("RenderBinary cert.pem application/pkix-cert", RequestLogPlugin.result(result)); } @Test public void logsReason_forError() { Forbidden forbidden = new Forbidden("User signature not valid!"); assertEquals("Forbidden \"User signature not valid!\"", RequestLogPlugin.result(forbidden)); BadRequest badRequest = new BadRequest("input error!"); assertEquals("BadRequest \"input error!\"", RequestLogPlugin.result(badRequest)); EvilRequest evilRequest=new EvilRequest("evil request"); assertEquals("EvilRequest \"evil request\"", RequestLogPlugin.result(evilRequest)); } private void setQueryString(String params) { try { request.params.data.putAll(UrlEncodedParser.parseQueryString(new ByteArrayInputStream(params.getBytes("UTF-8")))); } catch (UnsupportedEncodingException e) { throw new RuntimeException(e); } } }