diff --git a/pom.xml b/pom.xml index 999f93b..219d392 100644 --- a/pom.xml +++ b/pom.xml @@ -108,6 +108,13 @@ javax.inject 1 + + + junit + junit + 4.8.1 + test + diff --git a/src/main/java/biz/neustar/pagerduty/util/PagerDutyHttpClient.java b/src/main/java/biz/neustar/pagerduty/util/PagerDutyHttpClient.java index 6b4f340..e585b5a 100644 --- a/src/main/java/biz/neustar/pagerduty/util/PagerDutyHttpClient.java +++ b/src/main/java/biz/neustar/pagerduty/util/PagerDutyHttpClient.java @@ -1,9 +1,13 @@ package biz.neustar.pagerduty.util; -import biz.neustar.pagerduty.util.Version; +import javax.inject.Inject; +import javax.inject.Named; +import javax.inject.Singleton; + import org.apache.http.HttpHost; import org.apache.http.auth.AuthScope; import org.apache.http.auth.AuthState; +import org.apache.http.auth.Credentials; import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.client.AuthCache; import org.apache.http.client.CredentialsProvider; @@ -13,6 +17,7 @@ import org.apache.http.conn.scheme.SchemeRegistry; import org.apache.http.conn.ssl.SSLSocketFactory; import org.apache.http.impl.auth.BasicScheme; +import org.apache.http.impl.auth.RFC2617Scheme; import org.apache.http.impl.client.BasicAuthCache; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager; @@ -22,15 +27,15 @@ import org.apache.http.protocol.HttpContext; import org.apache.http.protocol.HttpRequestExecutor; -import javax.inject.Inject; -import javax.inject.Named; -import javax.inject.Singleton; - @Singleton public class PagerDutyHttpClient extends DefaultHttpClient { private String subdomain; private AuthScope authScope; - private UsernamePasswordCredentials creds; + private Credentials creds; + private enum AuthType { + BASIC, TOKEN + }; + private AuthType authType; @Inject public PagerDutyHttpClient(@Named("pagerduty.subdomain") String subdomain, @@ -38,13 +43,25 @@ public PagerDutyHttpClient(@Named("pagerduty.subdomain") String subdomain, @Named("pagerduty.password") String password) { this.subdomain = subdomain; authScope = new AuthScope(subdomain + ".pagerduty.com", 443); + authType = AuthType.BASIC; creds = new UsernamePasswordCredentials(username, password); } + @Inject + public PagerDutyHttpClient(@Named("pagerduty.subdomain") String subdomain, + @Named("pagerduty.token") String token) { + this.subdomain = subdomain; + authScope = new AuthScope(subdomain + ".pagerduty.com", 443); + authType = AuthType.TOKEN; + creds = new TokenAuthCredentials(token); + } + @Override protected CredentialsProvider createCredentialsProvider() { CredentialsProvider provider = super.createCredentialsProvider(); - provider.setCredentials(authScope, creds); + if (null != creds) { + provider.setCredentials(authScope, creds); + } return provider; } @@ -57,18 +74,22 @@ protected HttpRequestExecutor createRequestExecutor() { @Override protected HttpContext createHttpContext() { HttpContext ctx = super.createHttpContext(); - + RFC2617Scheme authScheme = null; AuthCache authCache = new BasicAuthCache(); - // Generate BASIC scheme object and add it to the local auth cache - BasicScheme basicAuth = new BasicScheme(); - HttpHost host = new HttpHost(subdomain + ".pagerduty.com", 443, "https"); - authCache.put(host, basicAuth); + if (AuthType.BASIC.equals(authType)) { + authScheme = new BasicScheme(); + } else if (AuthType.TOKEN.equals(authType)) { + authScheme = new TokenAuthScheme(); + } + + HttpHost host = new HttpHost(subdomain + ".pagerduty.com", 443, "https"); + authCache.put(host, authScheme); // Add AuthCache to the execution context ctx.setAttribute(ClientContext.AUTH_CACHE, authCache); AuthState state = new AuthState(); - state.setAuthScheme(basicAuth); + state.setAuthScheme(authScheme); state.setAuthScope(authScope); state.setCredentials(creds); ctx.setAttribute(ClientContext.TARGET_AUTH_STATE, state); diff --git a/src/main/java/biz/neustar/pagerduty/util/TokenAuthCredentials.java b/src/main/java/biz/neustar/pagerduty/util/TokenAuthCredentials.java new file mode 100644 index 0000000..6ae9e67 --- /dev/null +++ b/src/main/java/biz/neustar/pagerduty/util/TokenAuthCredentials.java @@ -0,0 +1,24 @@ +package biz.neustar.pagerduty.util; + +import java.security.Principal; + +import org.apache.http.auth.Credentials; + +public class TokenAuthCredentials implements Credentials { + private final String token; + + public TokenAuthCredentials(final String token) { + this.token = token; + } + + @Override + public String getPassword() { + return token; + } + + @Override + public Principal getUserPrincipal() { + return null; + } + +} diff --git a/src/main/java/biz/neustar/pagerduty/util/TokenAuthScheme.java b/src/main/java/biz/neustar/pagerduty/util/TokenAuthScheme.java new file mode 100644 index 0000000..939d967 --- /dev/null +++ b/src/main/java/biz/neustar/pagerduty/util/TokenAuthScheme.java @@ -0,0 +1,66 @@ +package biz.neustar.pagerduty.util; + +import org.apache.http.Header; +import org.apache.http.HttpRequest; +import org.apache.http.auth.AUTH; +import org.apache.http.auth.AuthenticationException; +import org.apache.http.auth.Credentials; +import org.apache.http.impl.auth.RFC2617Scheme; +import org.apache.http.message.BufferedHeader; +import org.apache.http.protocol.BasicHttpContext; +import org.apache.http.protocol.HttpContext; +import org.apache.http.util.CharArrayBuffer; + +public class TokenAuthScheme extends RFC2617Scheme { + public static final String TOKEN_HEADER_PREAMBLE = ": Token token="; + private boolean complete; + + public TokenAuthScheme() { + this.complete = false; + } + + @Override + public Header authenticate(Credentials creds, HttpRequest request) + throws AuthenticationException { + return authenticate(creds, request, new BasicHttpContext()); + } + + @Override + public String getSchemeName() { + return "token"; + } + + @Override + public boolean isComplete() { + return this.complete; + } + + @Override + public boolean isConnectionBased() { + return false; + } + + /* (non-Javadoc) + * @see org.apache.http.impl.auth.AuthSchemeBase#authenticate(org.apache.http.auth.Credentials, org.apache.http.HttpRequest, org.apache.http.protocol.HttpContext) + */ + @Override + public Header authenticate(Credentials credentials, HttpRequest request, + HttpContext context) throws AuthenticationException { + if (credentials instanceof TokenAuthCredentials) { + TokenAuthCredentials tokenCredentials = (TokenAuthCredentials) credentials; + CharArrayBuffer buffer = new CharArrayBuffer(32); + if (isProxy()) { + buffer.append(AUTH.PROXY_AUTH_RESP); + } else { + buffer.append(AUTH.WWW_AUTH_RESP); + } + buffer.append(TOKEN_HEADER_PREAMBLE); + buffer.append(tokenCredentials.getPassword()); + + return new BufferedHeader(buffer); + } else { + return super.authenticate(credentials, request, context); + } + } + +} diff --git a/src/test/java/biz/neustar/pagerduty/util/PagerDutyHttpClientTest.java b/src/test/java/biz/neustar/pagerduty/util/PagerDutyHttpClientTest.java new file mode 100644 index 0000000..56b26e1 --- /dev/null +++ b/src/test/java/biz/neustar/pagerduty/util/PagerDutyHttpClientTest.java @@ -0,0 +1,60 @@ +package biz.neustar.pagerduty.util; + +import static org.junit.Assert.*; + +import org.apache.http.auth.AuthScope; +import org.apache.http.auth.AuthState; +import org.apache.http.auth.Credentials; +import org.apache.http.client.CredentialsProvider; +import org.apache.http.client.protocol.ClientContext; +import org.apache.http.protocol.HttpContext; +import org.junit.Test; + +public class PagerDutyHttpClientTest { + + @Test + public void testBasicAuthConstructor() { + AuthScope authScope = new AuthScope("example.pagerduty.com", 443); + PagerDutyHttpClient client = new PagerDutyHttpClient("example", "user", "pass"); + CredentialsProvider provider = client.createCredentialsProvider(); + assertNotNull(provider); + + Credentials creds = provider.getCredentials(authScope); + assertNotNull(creds); + assertEquals("pass", creds.getPassword()); + } + + @Test + public void testTokenAuthConstructor() { + AuthScope authScope = new AuthScope("example.pagerduty.com", 443); + PagerDutyHttpClient client = new PagerDutyHttpClient("example", "token"); + CredentialsProvider provider = client.createCredentialsProvider(); + assertNotNull(provider); + + Credentials creds = provider.getCredentials(authScope); + assertNotNull(creds); + assertEquals("token", creds.getPassword()); + } + + @Test + public void testCreateHttpContextTokenAuth() { + AuthScope authScope = new AuthScope("example.pagerduty.com", 443); + PagerDutyHttpClient client = new PagerDutyHttpClient("example", "token"); + HttpContext httpContext = client.createHttpContext(); + assertNotNull(httpContext); + + AuthState state = (AuthState)httpContext.getAttribute(ClientContext.TARGET_AUTH_STATE); + + assertNotNull(state.getAuthScheme()); + assertTrue(state.getAuthScheme() instanceof TokenAuthScheme); + + assertNotNull(state.getAuthScope()); + assertEquals(authScope, state.getAuthScope()); + + assertNotNull(state.getCredentials()); + assertTrue(state.getCredentials() instanceof TokenAuthCredentials); + TokenAuthCredentials tokenCreds = (TokenAuthCredentials)state.getCredentials(); + assertEquals("token", tokenCreds.getPassword()); + } + +} diff --git a/src/test/java/biz/neustar/pagerduty/util/TokenAuthSchemeTest.java b/src/test/java/biz/neustar/pagerduty/util/TokenAuthSchemeTest.java new file mode 100644 index 0000000..0312873 --- /dev/null +++ b/src/test/java/biz/neustar/pagerduty/util/TokenAuthSchemeTest.java @@ -0,0 +1,29 @@ +package biz.neustar.pagerduty.util; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import org.apache.http.Header; +import org.apache.http.HttpRequest; +import org.apache.http.auth.AuthenticationException; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.protocol.BasicHttpContext; +import org.apache.http.protocol.HttpContext; +import org.junit.Test; + +public class TokenAuthSchemeTest { + + @Test + public void testAuthenticateCredentialsHttpRequestHttpContext() throws AuthenticationException { + TokenAuthScheme scheme = new TokenAuthScheme(); + TokenAuthCredentials creds = new TokenAuthCredentials("token_here"); + HttpRequest request = new HttpGet(); + HttpContext context = new BasicHttpContext(); + + Header header = scheme.authenticate(creds, request, context); + + assertNotNull(header); + assertEquals("Authorization: Token token=token_here", header.toString()); + } + +}