Merge pull request #374 from DataDog/mar-kolya/add-servlet-auth-tests

Add tests to servlet intrumentation to verify that username is set co…
This commit is contained in:
Tyler Benson 2018-06-26 15:16:49 +10:00 committed by GitHub
commit 05ef9ce8bd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 123 additions and 17 deletions

View File

@ -5,10 +5,18 @@ import datadog.trace.agent.test.TestUtils
import datadog.trace.api.DDSpanTypes
import datadog.trace.common.writer.ListWriter
import io.opentracing.util.GlobalTracer
import okhttp3.Credentials
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
import org.eclipse.jetty.http.HttpHeaders
import org.eclipse.jetty.http.security.Constraint
import org.eclipse.jetty.security.ConstraintMapping
import org.eclipse.jetty.security.ConstraintSecurityHandler
import org.eclipse.jetty.security.HashLoginService
import org.eclipse.jetty.security.LoginService
import org.eclipse.jetty.security.authentication.BasicAuthenticator
import org.eclipse.jetty.server.Server
import org.eclipse.jetty.servlet.ServletContextHandler
@ -34,9 +42,9 @@ class JettyServlet2Test extends AgentTestRunner {
}
})
// Uncomment when debugging:
.connectTimeout(1, TimeUnit.HOURS)
.writeTimeout(1, TimeUnit.HOURS)
.readTimeout(1, TimeUnit.HOURS)
// .connectTimeout(1, TimeUnit.HOURS)
// .writeTimeout(1, TimeUnit.HOURS)
// .readTimeout(1, TimeUnit.HOURS)
.build()
private Server jettyServer
@ -55,7 +63,11 @@ class JettyServlet2Test extends AgentTestRunner {
jettyServer = new Server(PORT)
servletContext = new ServletContextHandler()
ConstraintSecurityHandler security = setupAuthentication(jettyServer)
servletContext.setSecurityHandler(security)
servletContext.addServlet(TestServlet2.Sync, "/sync")
servletContext.addServlet(TestServlet2.Sync, "/auth/sync")
jettyServer.setHandler(servletContext)
jettyServer.start()
@ -82,11 +94,13 @@ class JettyServlet2Test extends AgentTestRunner {
def "test #path servlet call"() {
setup:
def request = new Request.Builder()
def requestBuilder = new Request.Builder()
.url("http://localhost:$PORT/$path")
.get()
.build()
def response = client.newCall(request).execute()
if (auth) {
requestBuilder.header(HttpHeaders.AUTHORIZATION, Credentials.basic("user", "password"))
}
def response = client.newCall(requestBuilder.build()).execute()
expect:
response.body().string().trim() == expectedResponse
@ -107,6 +121,9 @@ class JettyServlet2Test extends AgentTestRunner {
"component" "java-web-servlet"
"span.type" DDSpanTypes.WEB_SERVLET
"servlet.context" ""
if (auth) {
"user.principal" "user"
}
defaultTags()
}
}
@ -114,8 +131,9 @@ class JettyServlet2Test extends AgentTestRunner {
}
where:
path | expectedResponse
"sync" | "Hello Sync"
path | expectedResponse | auth
"sync" | "Hello Sync" | false
"auth/sync" | "Hello Sync" | true
}
def "test #path error servlet call"() {
@ -195,4 +213,37 @@ class JettyServlet2Test extends AgentTestRunner {
path | expectedResponse
"sync" | "Hello Sync"
}
/**
* Setup simple authentication for tests
* <p>
* requests to {@code /auth/*} need login 'user' and password 'password'
* <p>
* For details @see <a href="http://www.eclipse.org/jetty/documentation/9.3.x/embedded-examples.html">http://www.eclipse.org/jetty/documentation/9.3.x/embedded-examples.html</a>
*
* @param jettyServer server to attach login service
* @return SecurityHandler that can be assigned to servlet
*/
private ConstraintSecurityHandler setupAuthentication(Server jettyServer) {
ConstraintSecurityHandler security = new ConstraintSecurityHandler()
Constraint constraint = new Constraint()
constraint.setName("auth")
constraint.setAuthenticate(true)
constraint.setRoles("role")
ConstraintMapping mapping = new ConstraintMapping()
mapping.setPathSpec("/auth/*")
mapping.setConstraint(constraint)
security.setConstraintMappings(mapping)
security.setAuthenticator(new BasicAuthenticator())
LoginService loginService = new HashLoginService("TestRealm",
"src/test/resources/realm.properties")
security.setLoginService(loginService)
jettyServer.addBean(loginService)
security
}
}

View File

@ -0,0 +1 @@
user: password,role

View File

@ -5,12 +5,20 @@ import datadog.trace.agent.test.TestUtils
import datadog.trace.api.DDSpanTypes
import datadog.trace.common.writer.ListWriter
import io.opentracing.util.GlobalTracer
import okhttp3.Credentials
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
import org.eclipse.jetty.http.HttpHeaders
import org.eclipse.jetty.security.ConstraintMapping
import org.eclipse.jetty.security.ConstraintSecurityHandler
import org.eclipse.jetty.security.HashLoginService
import org.eclipse.jetty.security.LoginService
import org.eclipse.jetty.security.authentication.BasicAuthenticator
import org.eclipse.jetty.server.Server
import org.eclipse.jetty.servlet.ServletContextHandler
import org.eclipse.jetty.util.security.Constraint
import java.lang.reflect.Field
import java.util.concurrent.CountDownLatch
@ -35,9 +43,9 @@ class JettyServlet3Test extends AgentTestRunner {
}
})
// Uncomment when debugging:
// .connectTimeout(1, TimeUnit.HOURS)
// .writeTimeout(1, TimeUnit.HOURS)
// .readTimeout(1, TimeUnit.HOURS)
// .connectTimeout(1, TimeUnit.HOURS)
// .writeTimeout(1, TimeUnit.HOURS)
// .readTimeout(1, TimeUnit.HOURS)
.build()
private Server jettyServer
@ -56,8 +64,13 @@ class JettyServlet3Test extends AgentTestRunner {
jettyServer = new Server(PORT)
servletContext = new ServletContextHandler()
ConstraintSecurityHandler security = setupAuthentication(jettyServer)
servletContext.setSecurityHandler(security)
servletContext.addServlet(TestServlet3.Sync, "/sync")
servletContext.addServlet(TestServlet3.Sync, "/auth/sync")
servletContext.addServlet(TestServlet3.Async, "/async")
servletContext.addServlet(TestServlet3.Async, "/auth/async")
jettyServer.setHandler(servletContext)
jettyServer.start()
@ -84,11 +97,13 @@ class JettyServlet3Test extends AgentTestRunner {
def "test #path servlet call"() {
setup:
def request = new Request.Builder()
def requestBuilder = new Request.Builder()
.url("http://localhost:$PORT/$path")
.get()
.build()
def response = client.newCall(request).execute()
if (auth) {
requestBuilder.header(HttpHeaders.AUTHORIZATION, Credentials.basic("user", "password"))
}
def response = client.newCall(requestBuilder.build()).execute()
expect:
response.body().string().trim() == expectedResponse
@ -110,6 +125,9 @@ class JettyServlet3Test extends AgentTestRunner {
"span.type" DDSpanTypes.WEB_SERVLET
"servlet.context" ""
"http.status_code" 200
if (auth) {
"user.principal" "user"
}
defaultTags()
}
}
@ -117,9 +135,11 @@ class JettyServlet3Test extends AgentTestRunner {
}
where:
path | expectedResponse
"async" | "Hello Async"
"sync" | "Hello Sync"
path | expectedResponse | auth
"async" | "Hello Async" | false
"sync" | "Hello Sync" | false
"auth/async" | "Hello Async" | true
"auth/sync" | "Hello Sync" | true
}
def "servlet instrumentation clears state after async request"() {
@ -227,4 +247,37 @@ class JettyServlet3Test extends AgentTestRunner {
path | expectedResponse
"sync" | "Hello Sync"
}
/**
* Setup simple authentication for tests
* <p>
* requests to {@code /auth/*} need login 'user' and password 'password'
* <p>
* For details @see <a href="http://www.eclipse.org/jetty/documentation/9.3.x/embedded-examples.html">http://www.eclipse.org/jetty/documentation/9.3.x/embedded-examples.html</a>
*
* @param jettyServer server to attach login service
* @return SecurityHandler that can be assigned to servlet
*/
private ConstraintSecurityHandler setupAuthentication(Server jettyServer) {
ConstraintSecurityHandler security = new ConstraintSecurityHandler()
Constraint constraint = new Constraint()
constraint.setName("auth")
constraint.setAuthenticate(true)
constraint.setRoles("role")
ConstraintMapping mapping = new ConstraintMapping()
mapping.setPathSpec("/auth/*")
mapping.setConstraint(constraint)
security.setConstraintMappings(mapping)
security.setAuthenticator(new BasicAuthenticator())
LoginService loginService = new HashLoginService("TestRealm",
"src/test/resources/realm.properties")
security.setLoginService(loginService)
jettyServer.addBean(loginService)
security
}
}

View File

@ -0,0 +1 @@
user: password,role