diff --git a/apis/oauth/src/main/java/org/jclouds/oauth/v2/OAuthApi.java b/apis/oauth/src/main/java/org/jclouds/oauth/v2/OAuthApi.java
index 4a12d8d1ed..d3082fc3e2 100644
--- a/apis/oauth/src/main/java/org/jclouds/oauth/v2/OAuthApi.java
+++ b/apis/oauth/src/main/java/org/jclouds/oauth/v2/OAuthApi.java
@@ -16,17 +16,18 @@
*/
package org.jclouds.oauth.v2;
+import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
+
import java.io.Closeable;
import javax.inject.Named;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
-import javax.ws.rs.core.MediaType;
+import org.jclouds.oauth.v2.binders.OAuthTokenBinder;
import org.jclouds.oauth.v2.config.Authentication;
import org.jclouds.oauth.v2.domain.Token;
import org.jclouds.oauth.v2.domain.TokenRequest;
-import org.jclouds.oauth.v2.handlers.OAuthTokenBinder;
import org.jclouds.rest.AuthorizationException;
import org.jclouds.rest.annotations.BinderParam;
import org.jclouds.rest.annotations.Endpoint;
@@ -55,6 +56,6 @@ public interface OAuthApi extends Closeable {
*/
@Named("authenticate")
@POST
- @Consumes(MediaType.APPLICATION_JSON)
+ @Consumes(APPLICATION_JSON)
Token authenticate(@BinderParam(OAuthTokenBinder.class) TokenRequest tokenRequest) throws AuthorizationException;
}
diff --git a/apis/oauth/src/main/java/org/jclouds/oauth/v2/json/JWTTokenRequestFormat.java b/apis/oauth/src/main/java/org/jclouds/oauth/v2/binders/OAuthTokenBinder.java
similarity index 69%
rename from apis/oauth/src/main/java/org/jclouds/oauth/v2/json/JWTTokenRequestFormat.java
rename to apis/oauth/src/main/java/org/jclouds/oauth/v2/binders/OAuthTokenBinder.java
index 41d98048c8..e62d9c73f3 100644
--- a/apis/oauth/src/main/java/org/jclouds/oauth/v2/json/JWTTokenRequestFormat.java
+++ b/apis/oauth/src/main/java/org/jclouds/oauth/v2/binders/OAuthTokenBinder.java
@@ -14,38 +14,34 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.jclouds.oauth.v2.json;
+package org.jclouds.oauth.v2.binders;
import static com.google.common.base.Charsets.UTF_8;
import static com.google.common.base.Joiner.on;
import static com.google.common.io.BaseEncoding.base64Url;
import static org.jclouds.io.Payloads.newUrlEncodedFormPayload;
-import java.util.Set;
-
import javax.inject.Inject;
import org.jclouds.http.HttpRequest;
import org.jclouds.io.Payload;
import org.jclouds.json.Json;
import org.jclouds.oauth.v2.domain.TokenRequest;
-import org.jclouds.oauth.v2.domain.TokenRequestFormat;
+import org.jclouds.rest.Binder;
import com.google.common.base.Function;
import com.google.common.collect.ImmutableMultimap;
-import com.google.common.collect.ImmutableSet;
/**
* Formats a token request into JWT format namely:
- * - transforms the token request to json
- * - creates the base64 header.claimset portions of the payload.
- * - uses the provided signer function to create a signature
- * - creates the full url encoded payload as described in:
- * https://developers.google.com/accounts/docs/OAuth2ServiceAccount
- *
+ *
+ * - Transforms the token request to json.
+ * - Creates the base64 header.claimset portions of the payload.
+ * - Uses the provided signer function to create a signature.
+ * - Creates the full url encoded payload as described in: OAuth2ServiceAccount
+ *
*/
-public class JWTTokenRequestFormat implements TokenRequestFormat {
-
+public final class OAuthTokenBinder implements Binder {
private static final String ASSERTION_FORM_PARAM = "assertion";
private static final String GRANT_TYPE_FORM_PARAM = "grant_type";
private static final String GRANT_TYPE_JWT_BEARER = "urn:ietf:params:oauth:grant-type:jwt-bearer";
@@ -53,13 +49,13 @@ public class JWTTokenRequestFormat implements TokenRequestFormat {
private final Function signer;
private final Json json;
- @Inject JWTTokenRequestFormat(Function signer, Json json) {
+ @Inject OAuthTokenBinder(Function signer, Json json) {
this.signer = signer;
this.json = json;
}
- @Override public R formatRequest(R request, TokenRequest tokenRequest) {
-
+ @Override public R bindToRequest(R request, Object input) {
+ TokenRequest tokenRequest = (TokenRequest) input;
String encodedHeader = json.toJson(tokenRequest.header());
String encodedClaimSet = json.toJson(tokenRequest.claimSet());
@@ -72,18 +68,9 @@ public class JWTTokenRequestFormat implements TokenRequestFormat {
// the final assertion in base 64 encoded {header}.{claimSet}.{signature} format
String assertion = on(".").join(encodedHeader, encodedClaimSet, encodedSignature);
Payload payload = newUrlEncodedFormPayload(ImmutableMultimap. builder()
- .put(GRANT_TYPE_FORM_PARAM, GRANT_TYPE_JWT_BEARER)
- .put(ASSERTION_FORM_PARAM, assertion).build());
+ .put(GRANT_TYPE_FORM_PARAM, GRANT_TYPE_JWT_BEARER)
+ .put(ASSERTION_FORM_PARAM, assertion).build());
return (R) request.toBuilder().payload(payload).build();
}
-
- @Override public String type() {
- return "JWT";
- }
-
- @Override public Set requiredClaims() {
- // exp and ist (expiration and emission times) are assumed mandatory already
- return ImmutableSet.of("iss", "scope", "aud");
- }
}
diff --git a/apis/oauth/src/main/java/org/jclouds/oauth/v2/domain/TokenRequestFormat.java b/apis/oauth/src/main/java/org/jclouds/oauth/v2/domain/TokenRequestFormat.java
deleted file mode 100644
index 7099592e01..0000000000
--- a/apis/oauth/src/main/java/org/jclouds/oauth/v2/domain/TokenRequestFormat.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jclouds.oauth.v2.domain;
-
-import com.google.inject.ImplementedBy;
-import org.jclouds.http.HttpRequest;
-import org.jclouds.oauth.v2.json.JWTTokenRequestFormat;
-
-import java.util.Set;
-
-/**
- * Transforms a TokenRequest into a specific format (e.g. JWT token)
- */
-@ImplementedBy(JWTTokenRequestFormat.class)
-public interface TokenRequestFormat {
-
- /**
- * Transforms the provided HttpRequest into a particular token request with a specific format.
- */
- R formatRequest(R httpRequest, TokenRequest tokenRequest);
-
- /**
- * The name of the type of the token request, e.g., "JWT"
- */
- String type();
-
- /**
- * The claims that must be present in the token request for it to be valid.
- */
- Set requiredClaims();
-}
diff --git a/apis/oauth/src/main/java/org/jclouds/oauth/v2/filters/BearerTokenAuthenticator.java b/apis/oauth/src/main/java/org/jclouds/oauth/v2/filters/BearerTokenAuthenticator.java
index 779ba44095..5ff8c5091c 100644
--- a/apis/oauth/src/main/java/org/jclouds/oauth/v2/filters/BearerTokenAuthenticator.java
+++ b/apis/oauth/src/main/java/org/jclouds/oauth/v2/filters/BearerTokenAuthenticator.java
@@ -16,26 +16,24 @@
*/
package org.jclouds.oauth.v2.filters;
-import com.google.common.base.Supplier;
+import static java.lang.String.format;
+
+import javax.inject.Inject;
+
import org.jclouds.http.HttpException;
import org.jclouds.http.HttpRequest;
import org.jclouds.oauth.v2.domain.OAuthCredentials;
-import javax.inject.Inject;
-import javax.inject.Singleton;
+import com.google.common.base.Supplier;
-@Singleton
-public class BearerTokenAuthenticator implements OAuthAuthenticationFilter {
+public final class BearerTokenAuthenticator implements OAuthAuthenticationFilter {
private final Supplier creds;
- @Inject
- BearerTokenAuthenticator(final Supplier creds) {
+ @Inject BearerTokenAuthenticator(Supplier creds) {
this.creds = creds;
}
- @Override
- public HttpRequest filter(HttpRequest request) throws HttpException {
- return request.toBuilder().addHeader("Authorization", String.format("%s %s",
- "Bearer ", creds.get().credential)).build();
+ @Override public HttpRequest filter(HttpRequest request) throws HttpException {
+ return request.toBuilder().addHeader("Authorization", format("%s %s", "Bearer ", creds.get().credential)).build();
}
}
diff --git a/apis/oauth/src/main/java/org/jclouds/oauth/v2/filters/OAuthAuthenticator.java b/apis/oauth/src/main/java/org/jclouds/oauth/v2/filters/OAuthAuthenticator.java
index 40fc0cfd37..28a2c15a5c 100644
--- a/apis/oauth/src/main/java/org/jclouds/oauth/v2/filters/OAuthAuthenticator.java
+++ b/apis/oauth/src/main/java/org/jclouds/oauth/v2/filters/OAuthAuthenticator.java
@@ -16,47 +16,41 @@
*/
package org.jclouds.oauth.v2.filters;
-import com.google.common.base.Function;
-import com.google.common.cache.LoadingCache;
+import static com.google.common.base.Preconditions.checkState;
+
+import javax.inject.Inject;
+
import org.jclouds.http.HttpException;
import org.jclouds.http.HttpRequest;
import org.jclouds.oauth.v2.domain.Token;
import org.jclouds.oauth.v2.domain.TokenRequest;
import org.jclouds.rest.internal.GeneratedHttpRequest;
-import javax.inject.Inject;
-import javax.inject.Singleton;
-
-import static com.google.common.base.Preconditions.checkState;
+import com.google.common.base.Function;
+import com.google.common.cache.LoadingCache;
/**
* To be used by client applications to embed an OAuth authentication in their REST requests.
*
* TODO when we're able to use the OAuthAuthentication an this should be used automatically
*/
-@Singleton
-public class OAuthAuthenticator implements OAuthAuthenticationFilter {
+public final class OAuthAuthenticator implements OAuthAuthenticationFilter {
private Function tokenRequestBuilder;
private Function tokenFetcher;
- @Inject
- OAuthAuthenticator(Function tokenRequestBuilder, LoadingCache tokenFetcher) {
+ @Inject OAuthAuthenticator(Function tokenRequestBuilder,
+ LoadingCache tokenFetcher) {
this.tokenRequestBuilder = tokenRequestBuilder;
this.tokenFetcher = tokenFetcher;
}
- @Override
- public HttpRequest filter(HttpRequest request) throws HttpException {
+ @Override public HttpRequest filter(HttpRequest request) throws HttpException {
checkState(request instanceof GeneratedHttpRequest, "request must be an instance of GeneratedHttpRequest");
GeneratedHttpRequest generatedHttpRequest = GeneratedHttpRequest.class.cast(request);
TokenRequest tokenRequest = tokenRequestBuilder.apply(generatedHttpRequest);
Token token = tokenFetcher.apply(tokenRequest);
return request.toBuilder().addHeader("Authorization", String.format("%s %s",
token.tokenType(), token.accessToken())).build();
-
}
-
-
}
diff --git a/apis/oauth/src/main/java/org/jclouds/oauth/v2/functions/BuildTokenRequest.java b/apis/oauth/src/main/java/org/jclouds/oauth/v2/functions/BuildTokenRequest.java
index 664dcab6ea..bcce0047ad 100644
--- a/apis/oauth/src/main/java/org/jclouds/oauth/v2/functions/BuildTokenRequest.java
+++ b/apis/oauth/src/main/java/org/jclouds/oauth/v2/functions/BuildTokenRequest.java
@@ -24,22 +24,21 @@ import static org.jclouds.oauth.v2.config.OAuthProperties.SIGNATURE_OR_MAC_ALGOR
import java.util.Collections;
import java.util.LinkedHashMap;
+import java.util.List;
import java.util.Map;
-import javax.inject.Singleton;
-
import org.jclouds.Constants;
import org.jclouds.oauth.v2.config.OAuthScopes;
import org.jclouds.oauth.v2.domain.ClaimSet;
import org.jclouds.oauth.v2.domain.Header;
import org.jclouds.oauth.v2.domain.OAuthCredentials;
import org.jclouds.oauth.v2.domain.TokenRequest;
-import org.jclouds.oauth.v2.domain.TokenRequestFormat;
import org.jclouds.rest.internal.GeneratedHttpRequest;
import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.base.Supplier;
+import com.google.common.collect.ImmutableList;
import com.google.common.reflect.Invokable;
import com.google.inject.Inject;
import com.google.inject.name.Named;
@@ -51,50 +50,47 @@ import com.google.inject.name.Named;
*
* TODO scopes etc should come from the REST method and not from a global property
*/
-@Singleton
-public class BuildTokenRequest implements Function {
+public final class BuildTokenRequest implements Function {
+ // exp and ist (expiration and emission times) are assumed mandatory already
+ private static final List REQUIRED_CLAIMS = ImmutableList.of("iss", "scope", "aud");
private final String assertionTargetDescription;
private final String signatureAlgorithm;
- private final TokenRequestFormat tokenRequestFormat;
private final Supplier credentialsSupplier;
private final long tokenDuration;
@Inject(optional = true)
@Named(ADDITIONAL_CLAIMS)
- protected Map additionalClaims = Collections.emptyMap();
+ private Map additionalClaims = Collections.emptyMap();
@Inject(optional = true)
@Named(SCOPES)
- protected String globalScopes = null;
+ private String globalScopes = null;
// injectable so expect tests can override with a predictable value
@Inject(optional = true)
- protected Supplier timeSourceMillisSinceEpoch = new Supplier() {
+ private Supplier timeSourceMillisSinceEpoch = new Supplier() {
@Override
public Long get() {
return System.currentTimeMillis();
}
};
-
- @Inject
- public BuildTokenRequest(@Named(AUDIENCE) String assertionTargetDescription,
+
+ @Inject BuildTokenRequest(@Named(AUDIENCE) String assertionTargetDescription,
@Named(SIGNATURE_OR_MAC_ALGORITHM) String signatureAlgorithm,
- TokenRequestFormat tokenRequestFormat, Supplier credentialsSupplier,
+ Supplier credentialsSupplier,
@Named(Constants.PROPERTY_SESSION_INTERVAL) long tokenDuration) {
this.assertionTargetDescription = assertionTargetDescription;
this.signatureAlgorithm = signatureAlgorithm;
- this.tokenRequestFormat = tokenRequestFormat;
this.credentialsSupplier = credentialsSupplier;
this.tokenDuration = tokenDuration;
}
- @Override
- public TokenRequest apply(GeneratedHttpRequest request) {
+ @Override public TokenRequest apply(GeneratedHttpRequest request) {
long now = timeSourceMillisSinceEpoch.get() / 1000;
// fetch the token
- Header header = Header.create(signatureAlgorithm, tokenRequestFormat.type());
+ Header header = Header.create(signatureAlgorithm, "JWT");
Map claims = new LinkedHashMap();
claims.put("iss", credentialsSupplier.get().identity);
@@ -102,7 +98,7 @@ public class BuildTokenRequest implements Function invokable = request.getInvocation().getInvokable();
OAuthScopes classScopes = invokable.getOwnerType().getRawType().getAnnotation(OAuthScopes.class);
diff --git a/apis/oauth/src/main/java/org/jclouds/oauth/v2/functions/FetchToken.java b/apis/oauth/src/main/java/org/jclouds/oauth/v2/functions/FetchToken.java
index 593c8852ec..1a02cab748 100644
--- a/apis/oauth/src/main/java/org/jclouds/oauth/v2/functions/FetchToken.java
+++ b/apis/oauth/src/main/java/org/jclouds/oauth/v2/functions/FetchToken.java
@@ -16,26 +16,23 @@
*/
package org.jclouds.oauth.v2.functions;
-import com.google.common.base.Function;
+import javax.inject.Inject;
+
import org.jclouds.oauth.v2.OAuthApi;
import org.jclouds.oauth.v2.domain.Token;
import org.jclouds.oauth.v2.domain.TokenRequest;
-import javax.inject.Inject;
-import javax.inject.Singleton;
+import com.google.common.base.Function;
-@Singleton
-public class FetchToken implements Function {
+public final class FetchToken implements Function {
- private OAuthApi oAuthApi;
+ private final OAuthApi oAuthApi;
- @Inject
- public FetchToken(OAuthApi oAuthApi) {
+ @Inject FetchToken(OAuthApi oAuthApi) {
this.oAuthApi = oAuthApi;
}
- @Override
- public Token apply(TokenRequest input) {
+ @Override public Token apply(TokenRequest input) {
return this.oAuthApi.authenticate(input);
}
}
diff --git a/apis/oauth/src/main/java/org/jclouds/oauth/v2/functions/OAuthCredentialsSupplier.java b/apis/oauth/src/main/java/org/jclouds/oauth/v2/functions/OAuthCredentialsSupplier.java
index 45620c0eb9..cd7e3d6c66 100644
--- a/apis/oauth/src/main/java/org/jclouds/oauth/v2/functions/OAuthCredentialsSupplier.java
+++ b/apis/oauth/src/main/java/org/jclouds/oauth/v2/functions/OAuthCredentialsSupplier.java
@@ -16,27 +16,6 @@
*/
package org.jclouds.oauth.v2.functions;
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Charsets;
-import com.google.common.base.Supplier;
-import com.google.common.cache.CacheBuilder;
-import com.google.common.cache.CacheLoader;
-import com.google.common.cache.LoadingCache;
-import com.google.common.io.ByteSource;
-import com.google.common.util.concurrent.UncheckedExecutionException;
-import org.jclouds.domain.Credentials;
-import org.jclouds.location.Provider;
-import org.jclouds.oauth.v2.domain.OAuthCredentials;
-import org.jclouds.rest.AuthorizationException;
-
-import javax.inject.Inject;
-import javax.inject.Named;
-import javax.inject.Singleton;
-import java.io.IOException;
-import java.security.GeneralSecurityException;
-import java.security.KeyFactory;
-import java.security.PrivateKey;
-
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Throwables.propagate;
@@ -47,20 +26,42 @@ import static org.jclouds.oauth.v2.OAuthConstants.OAUTH_ALGORITHM_NAMES_TO_KEYFA
import static org.jclouds.oauth.v2.config.OAuthProperties.SIGNATURE_OR_MAC_ALGORITHM;
import static org.jclouds.util.Throwables2.getFirstThrowableOfType;
+import java.io.IOException;
+import java.security.GeneralSecurityException;
+import java.security.KeyFactory;
+import java.security.PrivateKey;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import org.jclouds.domain.Credentials;
+import org.jclouds.location.Provider;
+import org.jclouds.oauth.v2.domain.OAuthCredentials;
+import org.jclouds.rest.AuthorizationException;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Charsets;
+import com.google.common.base.Supplier;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
+import com.google.common.io.ByteSource;
+import com.google.common.util.concurrent.UncheckedExecutionException;
+
/**
* Loads {@link OAuthCredentials} from a pem private key using the KeyFactory obtained from the JWT Algorithm
* Name<->KeyFactory name mapping in OAuthConstants. The pem pk algorithm must match the KeyFactory algorithm.
*
* @see org.jclouds.oauth.v2.OAuthConstants#OAUTH_ALGORITHM_NAMES_TO_KEYFACTORY_ALGORITHM_NAMES
*/
-@Singleton
-public class OAuthCredentialsSupplier implements Supplier {
+@Singleton // due to cache
+public final class OAuthCredentialsSupplier implements Supplier {
private final Supplier creds;
private final LoadingCache keyCache;
- @Inject
- public OAuthCredentialsSupplier(@Provider Supplier creds, OAuthCredentialsForCredentials loader,
+ @Inject OAuthCredentialsSupplier(@Provider Supplier creds, OAuthCredentialsForCredentials loader,
@Named(SIGNATURE_OR_MAC_ALGORITHM) String signatureOrMacAlgorithm) {
this.creds = creds;
checkArgument(OAUTH_ALGORITHM_NAMES_TO_KEYFACTORY_ALGORITHM_NAMES.containsKey(signatureOrMacAlgorithm),
@@ -74,17 +75,15 @@ public class OAuthCredentialsSupplier implements Supplier {
* so that the private key is only recalculated once.
*/
@VisibleForTesting
- static class OAuthCredentialsForCredentials extends CacheLoader {
+ static final class OAuthCredentialsForCredentials extends CacheLoader {
private final String keyFactoryAlgorithm;
- @Inject
- public OAuthCredentialsForCredentials(@Named(SIGNATURE_OR_MAC_ALGORITHM) String signatureOrMacAlgorithm) {
+ @Inject OAuthCredentialsForCredentials(@Named(SIGNATURE_OR_MAC_ALGORITHM) String signatureOrMacAlgorithm) {
this.keyFactoryAlgorithm = OAUTH_ALGORITHM_NAMES_TO_KEYFACTORY_ALGORITHM_NAMES.get(checkNotNull(
signatureOrMacAlgorithm, "signatureOrMacAlgorithm"));
}
- @Override
- public OAuthCredentials load(Credentials in) {
+ @Override public OAuthCredentials load(Credentials in) {
try {
String identity = in.identity;
String privateKeyInPemFormat = in.credential;
@@ -108,18 +107,16 @@ public class OAuthCredentialsSupplier implements Supplier {
}
}
- @Override
- public OAuthCredentials get() {
+ @Override public OAuthCredentials get() {
try {
// loader always throws UncheckedExecutionException so no point in using get()
return keyCache.getUnchecked(checkNotNull(creds.get(), "credential supplier returned null"));
} catch (UncheckedExecutionException e) {
- Throwable authorizationException = getFirstThrowableOfType(e, AuthorizationException.class);
+ AuthorizationException authorizationException = getFirstThrowableOfType(e, AuthorizationException.class);
if (authorizationException != null) {
- throw (AuthorizationException) authorizationException;
+ throw authorizationException;
}
- throw propagate(e);
+ throw e;
}
}
-
}
diff --git a/apis/oauth/src/main/java/org/jclouds/oauth/v2/functions/SignOrProduceMacForToken.java b/apis/oauth/src/main/java/org/jclouds/oauth/v2/functions/SignOrProduceMacForToken.java
index 471812a8b1..647fcfae26 100644
--- a/apis/oauth/src/main/java/org/jclouds/oauth/v2/functions/SignOrProduceMacForToken.java
+++ b/apis/oauth/src/main/java/org/jclouds/oauth/v2/functions/SignOrProduceMacForToken.java
@@ -16,40 +16,42 @@
*/
package org.jclouds.oauth.v2.functions;
-import com.google.common.base.Function;
-import com.google.common.base.Supplier;
-import com.google.common.base.Throwables;
-import org.jclouds.oauth.v2.domain.OAuthCredentials;
+import static com.google.common.base.Preconditions.checkState;
+import static com.google.common.base.Throwables.propagate;
+import static java.lang.String.format;
+import static org.jclouds.oauth.v2.OAuthConstants.NO_ALGORITHM;
+import static org.jclouds.oauth.v2.OAuthConstants.OAUTH_ALGORITHM_NAMES_TO_SIGNATURE_ALGORITHM_NAMES;
+import static org.jclouds.oauth.v2.config.OAuthProperties.SIGNATURE_OR_MAC_ALGORITHM;
-import javax.annotation.PostConstruct;
-import javax.crypto.Mac;
-import javax.inject.Inject;
-import javax.inject.Named;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.Signature;
import java.security.SignatureException;
-import static com.google.common.base.Preconditions.checkState;
-import static java.lang.String.format;
-import static org.jclouds.oauth.v2.OAuthConstants.NO_ALGORITHM;
-import static org.jclouds.oauth.v2.OAuthConstants.OAUTH_ALGORITHM_NAMES_TO_SIGNATURE_ALGORITHM_NAMES;
-import static org.jclouds.oauth.v2.config.OAuthProperties.SIGNATURE_OR_MAC_ALGORITHM;
+import javax.annotation.PostConstruct;
+import javax.crypto.Mac;
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.jclouds.oauth.v2.domain.OAuthCredentials;
+
+import com.google.common.base.Function;
+import com.google.common.base.Supplier;
+import com.google.inject.Singleton;
/**
* Function that signs/produces mac's for OAuth tokens, provided a {@link Signature} or a {@link Mac} algorithm and
* {@link PrivateKey}
*/
-public class SignOrProduceMacForToken implements Function {
+@Singleton // due to signatureOrMacFunction
+public final class SignOrProduceMacForToken implements Function {
private final Supplier credentials;
private final String signatureOrMacAlgorithm;
private Function signatureOrMacFunction;
-
- @Inject
- public SignOrProduceMacForToken(@Named(SIGNATURE_OR_MAC_ALGORITHM) String signatureOrMacAlgorithm,
+ @Inject SignOrProduceMacForToken(@Named(SIGNATURE_OR_MAC_ALGORITHM) String signatureOrMacAlgorithm,
Supplier credentials) {
checkState(OAUTH_ALGORITHM_NAMES_TO_SIGNATURE_ALGORITHM_NAMES.containsKey(signatureOrMacAlgorithm),
format("the signature algorithm %s is not supported", signatureOrMacAlgorithm));
@@ -74,14 +76,13 @@ public class SignOrProduceMacForToken implements Function {
}
}
- @Override
- public byte[] apply(byte[] input) {
+ @Override public byte[] apply(byte[] input) {
return signatureOrMacFunction.apply(input);
}
private static class MessageAuthenticationCodeGenerator implements Function {
- private Mac mac;
+ private final Mac mac;
private MessageAuthenticationCodeGenerator(String macAlgorithm, PrivateKey privateKey) throws
NoSuchAlgorithmException, InvalidKeyException {
@@ -89,8 +90,7 @@ public class SignOrProduceMacForToken implements Function {
this.mac.init(privateKey);
}
- @Override
- public byte[] apply(byte[] input) {
+ @Override public byte[] apply(byte[] input) {
this.mac.update(input);
return this.mac.doFinal();
}
@@ -98,7 +98,7 @@ public class SignOrProduceMacForToken implements Function {
private static class SignatureGenerator implements Function {
- private Signature signature;
+ private final Signature signature;
private SignatureGenerator(String signatureAlgorithm, PrivateKey privateKey) throws NoSuchAlgorithmException,
InvalidKeyException {
@@ -106,13 +106,12 @@ public class SignOrProduceMacForToken implements Function {
this.signature.initSign(privateKey);
}
- @Override
- public byte[] apply(byte[] input) {
+ @Override public byte[] apply(byte[] input) {
try {
signature.update(input);
return signature.sign();
} catch (SignatureException e) {
- throw Throwables.propagate(e);
+ throw propagate(e);
}
}
}
diff --git a/apis/oauth/src/main/java/org/jclouds/oauth/v2/handlers/OAuthErrorHandler.java b/apis/oauth/src/main/java/org/jclouds/oauth/v2/handlers/OAuthErrorHandler.java
index 78d78440f7..ddc88a81fe 100644
--- a/apis/oauth/src/main/java/org/jclouds/oauth/v2/handlers/OAuthErrorHandler.java
+++ b/apis/oauth/src/main/java/org/jclouds/oauth/v2/handlers/OAuthErrorHandler.java
@@ -16,6 +16,9 @@
*/
package org.jclouds.oauth.v2.handlers;
+import static javax.ws.rs.core.Response.Status;
+import static org.jclouds.http.HttpUtils.closeClientButKeepContentStream;
+
import org.jclouds.http.HttpCommand;
import org.jclouds.http.HttpErrorHandler;
import org.jclouds.http.HttpResponse;
@@ -23,17 +26,8 @@ import org.jclouds.http.HttpResponseException;
import org.jclouds.rest.AuthorizationException;
import org.jclouds.rest.ResourceNotFoundException;
-import javax.inject.Singleton;
-
-import static javax.ws.rs.core.Response.Status;
-import static org.jclouds.http.HttpUtils.closeClientButKeepContentStream;
-
-/**
- * This will parse and set an appropriate exception on the command object.
- */
-@Singleton
-public class OAuthErrorHandler implements HttpErrorHandler {
- public void handleError(HttpCommand command, HttpResponse response) {
+public final class OAuthErrorHandler implements HttpErrorHandler {
+ @Override public void handleError(HttpCommand command, HttpResponse response) {
// it is important to always read fully and close streams
byte[] data = closeClientButKeepContentStream(response);
String message = data != null ? new String(data) : null;
diff --git a/apis/oauth/src/main/java/org/jclouds/oauth/v2/handlers/OAuthTokenBinder.java b/apis/oauth/src/main/java/org/jclouds/oauth/v2/handlers/OAuthTokenBinder.java
deleted file mode 100644
index 1030804714..0000000000
--- a/apis/oauth/src/main/java/org/jclouds/oauth/v2/handlers/OAuthTokenBinder.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jclouds.oauth.v2.handlers;
-
-import org.jclouds.http.HttpRequest;
-import org.jclouds.oauth.v2.domain.TokenRequest;
-import org.jclouds.oauth.v2.domain.TokenRequestFormat;
-import org.jclouds.rest.Binder;
-
-import javax.inject.Inject;
-import javax.inject.Singleton;
-
-/**
- * Generic implementation of a token binder. Uses a provided {@link TokenRequestFormat} to actually bind tokens to
- * requests.
- */
-@Singleton
-public class OAuthTokenBinder implements Binder {
-
- private final TokenRequestFormat tokenRequestFormat;
-
- @Inject
- OAuthTokenBinder(TokenRequestFormat tokenRequestFormat) {
- this.tokenRequestFormat = tokenRequestFormat;
- }
-
- @Override
- public R bindToRequest(R request, Object input) {
- return tokenRequestFormat.formatRequest(request, (TokenRequest) input);
- }
-}
diff --git a/apis/oauth/src/main/java/org/jclouds/oauth/v2/internal/SubtypeAdapterFactory.java b/apis/oauth/src/main/java/org/jclouds/oauth/v2/internal/SubtypeAdapterFactory.java
deleted file mode 100644
index f09bea6376..0000000000
--- a/apis/oauth/src/main/java/org/jclouds/oauth/v2/internal/SubtypeAdapterFactory.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jclouds.oauth.v2.internal;
-
-import com.google.gson.Gson;
-import com.google.gson.TypeAdapter;
-import com.google.gson.TypeAdapterFactory;
-import com.google.gson.reflect.TypeToken;
-
-/**
- * Type adapter used to serialize all subtypes of a value. This can be used to force serialization for an {@link
- * com.google.auto.value.AutoValue} generated class.
- */
-public abstract class SubtypeAdapterFactory extends TypeAdapter implements TypeAdapterFactory {
- private final Class baseClass;
-
- protected SubtypeAdapterFactory(Class baseClass) {
- this.baseClass = baseClass;
- }
-
- /** Accepts duty for any subtype. When using AutoValue properly, this will be the generated form. */
- @Override public TypeAdapter create(Gson gson, TypeToken typeToken) {
- if (!(baseClass.isAssignableFrom(typeToken.getRawType()))) {
- return null;
- }
- return (TypeAdapter) this;
- }
-}
diff --git a/apis/oauth/src/test/java/org/jclouds/oauth/v2/json/JWTTokenRequestFormatTest.java b/apis/oauth/src/test/java/org/jclouds/oauth/v2/binders/OAuthTokenBinderTest.java
similarity index 83%
rename from apis/oauth/src/test/java/org/jclouds/oauth/v2/json/JWTTokenRequestFormatTest.java
rename to apis/oauth/src/test/java/org/jclouds/oauth/v2/binders/OAuthTokenBinderTest.java
index bc82809cd3..b73d49bb05 100644
--- a/apis/oauth/src/test/java/org/jclouds/oauth/v2/json/JWTTokenRequestFormatTest.java
+++ b/apis/oauth/src/test/java/org/jclouds/oauth/v2/binders/OAuthTokenBinderTest.java
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.jclouds.oauth.v2.json;
+package org.jclouds.oauth.v2.binders;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertSame;
@@ -29,7 +29,6 @@ import org.jclouds.oauth.v2.OAuthTestUtils;
import org.jclouds.oauth.v2.domain.ClaimSet;
import org.jclouds.oauth.v2.domain.Header;
import org.jclouds.oauth.v2.domain.TokenRequest;
-import org.jclouds.oauth.v2.domain.TokenRequestFormat;
import org.jclouds.util.Strings2;
import org.testng.annotations.Test;
@@ -37,23 +36,23 @@ import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
-@Test(groups = "unit")
-public class JWTTokenRequestFormatTest {
+@Test(groups = "unit", testName = "OAuthTokenBinderTest")
+public class OAuthTokenBinderTest {
public static final String STRING_THAT_GENERATES_URL_UNSAFE_BASE64_ENCODING = "§1234567890'+±!\"#$%&/()" +
"=?*qwertyuiopº´WERTYUIOPªàsdfghjklç~ASDFGHJKLÇ^ZXCVBNM;:_@€";
public void testPayloadIsUrlSafe() throws IOException {
- TokenRequestFormat tokenRequestFormat = ContextBuilder.newBuilder(new OAuthApiMetadata()).overrides
+ OAuthTokenBinder tokenRequestFormat = ContextBuilder.newBuilder(new OAuthApiMetadata()).overrides
(OAuthTestUtils.defaultProperties(null)).build().utils()
- .injector().getInstance(TokenRequestFormat.class);
+ .injector().getInstance(OAuthTokenBinder.class);
Header header = Header.create("a", "b");
ClaimSet claimSet = ClaimSet.create(0, 0,
ImmutableMap.of("ist", STRING_THAT_GENERATES_URL_UNSAFE_BASE64_ENCODING));
TokenRequest tokenRequest = TokenRequest.create(header, claimSet);
- HttpRequest request = tokenRequestFormat.formatRequest(HttpRequest.builder().method("GET").endpoint
- ("http://localhost").build(), tokenRequest);
+ HttpRequest request = tokenRequestFormat.bindToRequest(
+ HttpRequest.builder().method("GET").endpoint("http://localhost").build(), tokenRequest);
assertNotNull(request.getPayload());