mirror of https://github.com/apache/jclouds.git
accomodate runtime credential changes
This commit is contained in:
parent
a7e4564c8e
commit
1ab3f0bb44
|
@ -37,11 +37,10 @@ import javax.inject.Singleton;
|
|||
|
||||
import org.jclouds.crypto.Crypto;
|
||||
import org.jclouds.date.TimeStamp;
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.http.HttpException;
|
||||
import org.jclouds.location.Provider;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.rest.annotations.Credential;
|
||||
import org.jclouds.rest.annotations.Identity;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Supplier;
|
||||
|
@ -58,8 +57,7 @@ import com.google.common.io.ByteProcessor;
|
|||
@Singleton
|
||||
public class ShareUrl implements Function<String, URI> {
|
||||
|
||||
private final String uid;
|
||||
private final byte[] key;
|
||||
private final Supplier<Credentials> creds;
|
||||
private final Supplier<URI> provider;
|
||||
private final javax.inject.Provider<Long> timeStampProvider;
|
||||
private final Crypto crypto;
|
||||
|
@ -72,10 +70,9 @@ public class ShareUrl implements Function<String, URI> {
|
|||
Logger signatureLog = Logger.NULL;
|
||||
|
||||
@Inject
|
||||
public ShareUrl(@Identity String uid, @Credential String encodedKey,
|
||||
@Provider Supplier<URI> provider, @TimeStamp javax.inject.Provider<Long> timeStampProvider, Crypto crypto) {
|
||||
this.uid = uid;
|
||||
this.key = base64().decode(encodedKey);
|
||||
public ShareUrl(@Provider Supplier<Credentials> creds, @Provider Supplier<URI> provider,
|
||||
@TimeStamp javax.inject.Provider<Long> timeStampProvider, Crypto crypto) {
|
||||
this.creds = creds;
|
||||
this.provider = provider;
|
||||
this.timeStampProvider = timeStampProvider;
|
||||
this.crypto = crypto;
|
||||
|
@ -87,7 +84,7 @@ public class ShareUrl implements Function<String, URI> {
|
|||
String expires = timeStampProvider.get().toString();
|
||||
String signature = signString(createStringToSign(requestedResource, expires));
|
||||
return uriBuilder(provider.get())
|
||||
.replaceQuery(ImmutableMap.of("uid", uid, "expires", expires, "signature", signature))
|
||||
.replaceQuery(ImmutableMap.of("uid", creds.get().identity, "expires", expires, "signature", signature))
|
||||
.appendPath(requestedResource).build();
|
||||
}
|
||||
|
||||
|
@ -95,14 +92,14 @@ public class ShareUrl implements Function<String, URI> {
|
|||
StringBuilder toSign = new StringBuilder();
|
||||
toSign.append("GET\n");
|
||||
toSign.append(requestedResource.toLowerCase()).append("\n");
|
||||
toSign.append(uid).append("\n");
|
||||
toSign.append(creds.get().identity).append("\n");
|
||||
toSign.append(expires);
|
||||
return toSign.toString();
|
||||
}
|
||||
|
||||
public String signString(String toSign) {
|
||||
try {
|
||||
ByteProcessor<byte[]> hmacSHA1 = asByteProcessor(crypto.hmacSHA1(key));
|
||||
ByteProcessor<byte[]> hmacSHA1 = asByteProcessor(crypto.hmacSHA1(base64().decode(creds.get().credential)));
|
||||
return base64().encode(readBytes(toInputStream(toSign), hmacSHA1));
|
||||
} catch (InvalidKeyException e) {
|
||||
throw propagate(e);
|
||||
|
|
|
@ -38,18 +38,18 @@ import javax.ws.rs.core.HttpHeaders;
|
|||
import org.jclouds.atmos.reference.AtmosHeaders;
|
||||
import org.jclouds.crypto.Crypto;
|
||||
import org.jclouds.date.TimeStamp;
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.http.HttpException;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpRequestFilter;
|
||||
import org.jclouds.http.HttpUtils;
|
||||
import org.jclouds.http.internal.SignatureWire;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.rest.annotations.Credential;
|
||||
import org.jclouds.rest.annotations.Identity;
|
||||
import org.jclouds.util.Strings2;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableMap.Builder;
|
||||
import com.google.common.collect.Multimaps;
|
||||
|
@ -67,8 +67,7 @@ import com.google.common.io.ByteProcessor;
|
|||
public class SignRequest implements HttpRequestFilter {
|
||||
|
||||
private final SignatureWire signatureWire;
|
||||
private final String uid;
|
||||
private final byte[] key;
|
||||
private final Supplier<Credentials> creds;
|
||||
private final Provider<String> timeStampProvider;
|
||||
private final Crypto crypto;
|
||||
private final HttpUtils utils;
|
||||
|
@ -81,12 +80,10 @@ public class SignRequest implements HttpRequestFilter {
|
|||
Logger signatureLog = Logger.NULL;
|
||||
|
||||
@Inject
|
||||
public SignRequest(SignatureWire signatureWire, @Identity String uid,
|
||||
@Credential String encodedKey, @TimeStamp Provider<String> timeStampProvider, Crypto crypto,
|
||||
HttpUtils utils) {
|
||||
public SignRequest(SignatureWire signatureWire, @org.jclouds.location.Provider Supplier<Credentials> creds,
|
||||
@TimeStamp Provider<String> timeStampProvider, Crypto crypto, HttpUtils utils) {
|
||||
this.signatureWire = signatureWire;
|
||||
this.uid = uid;
|
||||
this.key = base64().decode(encodedKey);
|
||||
this.creds = creds;
|
||||
this.timeStampProvider = timeStampProvider;
|
||||
this.crypto = crypto;
|
||||
this.utils = utils;
|
||||
|
@ -95,7 +92,7 @@ public class SignRequest implements HttpRequestFilter {
|
|||
@Override
|
||||
public HttpRequest filter(HttpRequest request) throws HttpException {
|
||||
Builder<String, String> builder = ImmutableMap.builder();
|
||||
builder.put(AtmosHeaders.UID, uid);
|
||||
builder.put(AtmosHeaders.UID, creds.get().identity);
|
||||
String date = timeStampProvider.get();
|
||||
builder.put(HttpHeaders.DATE, date);
|
||||
if (request.getHeaders().containsKey(AtmosHeaders.DATE))
|
||||
|
@ -130,7 +127,7 @@ public class SignRequest implements HttpRequestFilter {
|
|||
|
||||
public String signString(String toSign) {
|
||||
try {
|
||||
ByteProcessor<byte[]> hmacSHA1 = asByteProcessor(crypto.hmacSHA1(key));
|
||||
ByteProcessor<byte[]> hmacSHA1 = asByteProcessor(crypto.hmacSHA1(base64().decode(creds.get().credential)));
|
||||
return base64().encode(readBytes(toInputStream(toSign), hmacSHA1));
|
||||
} catch (Exception e) {
|
||||
throw new HttpException("error signing request", e);
|
||||
|
|
|
@ -18,11 +18,9 @@
|
|||
*/
|
||||
package org.jclouds.cloudstack.config;
|
||||
|
||||
import static com.google.common.base.Throwables.propagate;
|
||||
import static org.jclouds.rest.config.BinderUtils.bindHttpApi;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.jclouds.Constants;
|
||||
|
@ -280,15 +278,11 @@ public class CloudStackRestClientModule extends RestClientModule<CloudStackClien
|
|||
@Provides
|
||||
@Singleton
|
||||
protected Supplier<LoginResponse> provideLoginResponseSupplier(final LoadingCache<Credentials, LoginResponse> cache,
|
||||
@Provider final Credentials creds) {
|
||||
@Provider final Supplier<Credentials> creds) {
|
||||
return new Supplier<LoginResponse>() {
|
||||
@Override
|
||||
public LoginResponse get() {
|
||||
try {
|
||||
return cache.get(creds);
|
||||
} catch (ExecutionException e) {
|
||||
throw propagate(e.getCause());
|
||||
}
|
||||
return cache.getUnchecked(creds.get());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -38,16 +38,17 @@ import javax.inject.Named;
|
|||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.crypto.Crypto;
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.http.HttpException;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpUtils;
|
||||
import org.jclouds.http.internal.SignatureWire;
|
||||
import org.jclouds.location.Provider;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.rest.RequestSigner;
|
||||
import org.jclouds.rest.annotations.Credential;
|
||||
import org.jclouds.rest.annotations.Identity;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.collect.TreeMultimap;
|
||||
|
@ -63,8 +64,7 @@ import com.google.common.io.ByteProcessor;
|
|||
public class QuerySigner implements AuthenticationFilter, RequestSigner {
|
||||
|
||||
private final SignatureWire signatureWire;
|
||||
private final String accessKey;
|
||||
private final String secretKey;
|
||||
private final Supplier<Credentials> creds;
|
||||
private final Crypto crypto;
|
||||
private final HttpUtils utils;
|
||||
|
||||
|
@ -73,11 +73,9 @@ public class QuerySigner implements AuthenticationFilter, RequestSigner {
|
|||
private Logger signatureLog = Logger.NULL;
|
||||
|
||||
@Inject
|
||||
public QuerySigner(SignatureWire signatureWire, @Identity String accessKey, @Credential String secretKey,
|
||||
Crypto crypto, HttpUtils utils) {
|
||||
public QuerySigner(SignatureWire signatureWire, @Provider Supplier<Credentials> creds, Crypto crypto, HttpUtils utils) {
|
||||
this.signatureWire = signatureWire;
|
||||
this.accessKey = accessKey;
|
||||
this.secretKey = secretKey;
|
||||
this.creds = creds;
|
||||
this.crypto = crypto;
|
||||
this.utils = utils;
|
||||
}
|
||||
|
@ -103,7 +101,7 @@ public class QuerySigner implements AuthenticationFilter, RequestSigner {
|
|||
public String sign(String toSign) {
|
||||
String signature;
|
||||
try {
|
||||
ByteProcessor<byte[]> hmacSHA1 = asByteProcessor(crypto.hmacSHA1(secretKey.getBytes()));
|
||||
ByteProcessor<byte[]> hmacSHA1 = asByteProcessor(crypto.hmacSHA1(creds.get().credential.getBytes()));
|
||||
signature = base64().encode(readBytes(toInputStream(toSign), hmacSHA1));
|
||||
if (signatureWire.enabled())
|
||||
signatureWire.input(toInputStream(signature));
|
||||
|
@ -130,7 +128,7 @@ public class QuerySigner implements AuthenticationFilter, RequestSigner {
|
|||
|
||||
@VisibleForTesting
|
||||
void addSigningParams(Multimap<String, String> params) {
|
||||
params.replaceValues("apiKey", ImmutableList.of(accessKey));
|
||||
params.replaceValues("apiKey", ImmutableList.of(creds.get().identity));
|
||||
params.removeAll("signature");
|
||||
}
|
||||
|
||||
|
|
|
@ -28,8 +28,9 @@ import javax.inject.Inject;
|
|||
import org.jclouds.cloudstack.CloudStackClient;
|
||||
import org.jclouds.cloudstack.domain.User;
|
||||
import org.jclouds.cloudstack.predicates.UserPredicates;
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.location.Provider;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.rest.annotations.Identity;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Supplier;
|
||||
|
@ -45,18 +46,18 @@ public class GetCurrentUser implements Supplier<User> {
|
|||
protected Logger logger = Logger.NULL;
|
||||
|
||||
private final CloudStackClient client;
|
||||
private final String identity;
|
||||
private final Supplier<Credentials> creds;
|
||||
|
||||
@Inject
|
||||
public GetCurrentUser(CloudStackClient client, @Identity String identity) {
|
||||
public GetCurrentUser(CloudStackClient client, @Provider Supplier<Credentials> creds) {
|
||||
this.client = checkNotNull(client, "client");
|
||||
this.identity = checkNotNull(identity, "identity");
|
||||
this.creds = checkNotNull(creds, "creds");
|
||||
}
|
||||
|
||||
@Override
|
||||
public User get() {
|
||||
Iterable<User> users = Iterables.concat(client.getAccountClient().listAccounts());
|
||||
Predicate<User> apiKeyMatches = UserPredicates.apiKeyEquals(identity);
|
||||
Predicate<User> apiKeyMatches = UserPredicates.apiKeyEquals(creds.get().identity);
|
||||
User currentUser = null;
|
||||
try {
|
||||
currentUser = Iterables.find(users, apiKeyMatches);
|
||||
|
|
|
@ -62,13 +62,13 @@ import org.jclouds.compute.functions.DefaultCredentialsFromImageOrOverridingCred
|
|||
import org.jclouds.compute.strategy.PrioritizeCredentialsFromTemplate;
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.logging.slf4j.config.SLF4JLoggingModule;
|
||||
import org.jclouds.rest.annotations.Identity;
|
||||
import org.testng.annotations.AfterGroups;
|
||||
import org.testng.annotations.BeforeGroups;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.base.Suppliers;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
|
@ -103,7 +103,6 @@ public class CloudStackComputeServiceAdapterLiveTest extends BaseCloudStackClien
|
|||
@Override
|
||||
protected void configure() {
|
||||
bindProperties(binder(), setupProperties());
|
||||
bind(String.class).annotatedWith(Identity.class).toInstance(identity);
|
||||
bind(new TypeLiteral<Supplier<User>>() {
|
||||
}).annotatedWith(Memoized.class).to(GetCurrentUser.class).in(Scopes.SINGLETON);
|
||||
bind(new TypeLiteral<Supplier<Map<String, Network>>>() {
|
||||
|
@ -124,6 +123,12 @@ public class CloudStackComputeServiceAdapterLiveTest extends BaseCloudStackClien
|
|||
to(ZoneIdToZoneSupplier.class);
|
||||
install(new FactoryModuleBuilder().build(StaticNATVirtualMachineInNetwork.Factory.class));
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
Supplier<Credentials> supplyCredentials(){
|
||||
return Suppliers.ofInstance(new Credentials(identity, credential));
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
|
|
|
@ -21,9 +21,12 @@ package org.jclouds.ec2.options;
|
|||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.ec2.options.internal.BaseEC2RequestOptions;
|
||||
import org.jclouds.rest.annotations.Identity;
|
||||
import org.jclouds.location.Provider;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.inject.Inject;
|
||||
|
||||
|
@ -49,15 +52,16 @@ import com.google.inject.Inject;
|
|||
*/
|
||||
public class BundleInstanceS3StorageOptions extends BaseEC2RequestOptions {
|
||||
|
||||
@Inject(optional = true)
|
||||
@Identity
|
||||
String currentAwsAccessKeyId;
|
||||
@Inject
|
||||
@VisibleForTesting
|
||||
@Provider
|
||||
Supplier<Credentials> creds;
|
||||
|
||||
@Override
|
||||
public Multimap<String, String> buildFormParameters() {
|
||||
if (getAwsAccessKeyId() == null) {
|
||||
checkState(currentAwsAccessKeyId != null, "currentAwsAccessKeyId should have been injected");
|
||||
bucketOwnedBy(currentAwsAccessKeyId);
|
||||
checkState(creds != null, "creds should have been injected");
|
||||
bucketOwnedBy(creds.get().identity);
|
||||
}
|
||||
return super.buildFormParameters();
|
||||
}
|
||||
|
@ -82,11 +86,11 @@ public class BundleInstanceS3StorageOptions extends BaseEC2RequestOptions {
|
|||
|
||||
public static class Builder {
|
||||
/**
|
||||
* @see BundleInstanceS3StorageOptions#bucketOwnedBy(ccessKeyId)
|
||||
* @see BundleInstanceS3StorageOptions#bucketOwnedBy(accessKeyId)
|
||||
*/
|
||||
public static BundleInstanceS3StorageOptions bucketOwnedBy(String ccessKeyId) {
|
||||
public static BundleInstanceS3StorageOptions bucketOwnedBy(String accessKeyId) {
|
||||
BundleInstanceS3StorageOptions options = new BundleInstanceS3StorageOptions();
|
||||
return options.bucketOwnedBy(ccessKeyId);
|
||||
return options.bucketOwnedBy(accessKeyId);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -21,11 +21,13 @@ package org.jclouds.ec2.options;
|
|||
import static org.jclouds.ec2.options.BundleInstanceS3StorageOptions.Builder.bucketOwnedBy;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.http.options.HttpRequestOptions;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.base.Suppliers;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
/**
|
||||
* Tests possible uses of BundleInstanceS3StorageOptions and
|
||||
* BundleInstanceS3StorageOptions.Builder.*
|
||||
|
@ -56,7 +58,7 @@ public class BundleInstanceS3StorageOptionsTest {
|
|||
@Test
|
||||
public void testNullBucketOwnedBy() {
|
||||
BundleInstanceS3StorageOptions options = new BundleInstanceS3StorageOptions();
|
||||
options.currentAwsAccessKeyId = "foo";
|
||||
options.creds = Suppliers.ofInstance(new Credentials("foo", null));
|
||||
assertEquals(options.buildFormParameters().get("Storage.S3.AWSAccessKeyId"), ImmutableList.of("foo"));
|
||||
}
|
||||
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
package org.jclouds.openstack.keystone.v2_0.config;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Throwables.propagate;
|
||||
import static org.jclouds.rest.config.BinderUtils.bindHttpApi;
|
||||
|
||||
import java.util.Map;
|
||||
|
@ -194,15 +193,11 @@ public class KeystoneAuthenticationModule extends AbstractModule {
|
|||
@Provides
|
||||
@Singleton
|
||||
protected Supplier<Access> provideAccessSupplier(final LoadingCache<Credentials, Access> cache,
|
||||
@Provider final Credentials creds) {
|
||||
@Provider final Supplier<Credentials> creds) {
|
||||
return new Supplier<Access>() {
|
||||
@Override
|
||||
public Access get() {
|
||||
try {
|
||||
return cache.get(creds);
|
||||
} catch (ExecutionException e) {
|
||||
throw propagate(e.getCause());
|
||||
}
|
||||
return cache.getUnchecked(creds.get());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -45,6 +45,7 @@ import javax.ws.rs.core.HttpHeaders;
|
|||
import org.jclouds.Constants;
|
||||
import org.jclouds.crypto.Crypto;
|
||||
import org.jclouds.date.TimeStamp;
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.http.HttpException;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpRequestFilter;
|
||||
|
@ -52,12 +53,11 @@ import org.jclouds.http.HttpUtils;
|
|||
import org.jclouds.http.internal.SignatureWire;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.rest.RequestSigner;
|
||||
import org.jclouds.rest.annotations.Credential;
|
||||
import org.jclouds.rest.annotations.Identity;
|
||||
import org.jclouds.s3.util.S3Utils;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Multimap;
|
||||
|
@ -86,8 +86,7 @@ public class RequestAuthorizeSignature implements HttpRequestFilter, RequestSign
|
|||
"response-cache-control", "response-content-disposition", "response-content-encoding", "delete");
|
||||
|
||||
private final SignatureWire signatureWire;
|
||||
private final String accessKey;
|
||||
private final String secretKey;
|
||||
private final Supplier<Credentials> creds;
|
||||
private final Provider<String> timeStampProvider;
|
||||
private final Crypto crypto;
|
||||
private final HttpUtils utils;
|
||||
|
@ -105,15 +104,14 @@ public class RequestAuthorizeSignature implements HttpRequestFilter, RequestSign
|
|||
public RequestAuthorizeSignature(SignatureWire signatureWire, @Named(PROPERTY_AUTH_TAG) String authTag,
|
||||
@Named(PROPERTY_S3_VIRTUAL_HOST_BUCKETS) boolean isVhostStyle,
|
||||
@Named(PROPERTY_S3_SERVICE_PATH) String servicePath, @Named(PROPERTY_HEADER_TAG) String headerTag,
|
||||
@Identity String accessKey, @Credential String secretKey,
|
||||
@org.jclouds.location.Provider Supplier<Credentials> creds,
|
||||
@TimeStamp Provider<String> timeStampProvider, Crypto crypto, HttpUtils utils) {
|
||||
this.isVhostStyle = isVhostStyle;
|
||||
this.servicePath = servicePath;
|
||||
this.headerTag = headerTag;
|
||||
this.authTag = authTag;
|
||||
this.signatureWire = signatureWire;
|
||||
this.accessKey = accessKey;
|
||||
this.secretKey = secretKey;
|
||||
this.creds = creds;
|
||||
this.timeStampProvider = timeStampProvider;
|
||||
this.crypto = crypto;
|
||||
this.utils = utils;
|
||||
|
@ -128,7 +126,8 @@ public class RequestAuthorizeSignature implements HttpRequestFilter, RequestSign
|
|||
}
|
||||
|
||||
HttpRequest replaceAuthorizationHeader(HttpRequest request, String signature) {
|
||||
request = request.toBuilder().replaceHeader(HttpHeaders.AUTHORIZATION, authTag + " " + accessKey + ":" + signature).build();
|
||||
request = request.toBuilder()
|
||||
.replaceHeader(HttpHeaders.AUTHORIZATION, authTag + " " + creds.get().identity + ":" + signature).build();
|
||||
return request;
|
||||
}
|
||||
|
||||
|
@ -168,7 +167,7 @@ public class RequestAuthorizeSignature implements HttpRequestFilter, RequestSign
|
|||
|
||||
public String sign(String toSign) {
|
||||
try {
|
||||
ByteProcessor<byte[]> hmacSHA1 = asByteProcessor(crypto.hmacSHA1(secretKey.getBytes(UTF_8)));
|
||||
ByteProcessor<byte[]> hmacSHA1 = asByteProcessor(crypto.hmacSHA1(creds.get().credential.getBytes(UTF_8)));
|
||||
return base64().encode(readBytes(toInputStream(toSign), hmacSHA1));
|
||||
} catch (Exception e) {
|
||||
throw new HttpException("error signing request", e);
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
package org.jclouds.vcloud.config;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
import static org.jclouds.vcloud.reference.VCloudConstants.PROPERTY_VCLOUD_DEFAULT_ORG;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
@ -31,41 +30,31 @@ import org.jclouds.vcloud.domain.VCloudSession;
|
|||
import org.jclouds.vcloud.endpoints.Org;
|
||||
import org.jclouds.vcloud.suppliers.OnlyReferenceTypeFirstWithNameMatchingConfigurationKeyOrDefault;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.base.Suppliers;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Singleton
|
||||
public class DefaultOrgForUser implements Function<String, Supplier<ReferenceType>> {
|
||||
public class DefaultOrgForUser implements Supplier<ReferenceType> {
|
||||
|
||||
private final OnlyReferenceTypeFirstWithNameMatchingConfigurationKeyOrDefault selector;
|
||||
private final Supplier<VCloudSession> sessionSupplier;
|
||||
private final Supplier<VCloudSession> session;
|
||||
|
||||
@Inject
|
||||
public DefaultOrgForUser(ValueOfConfigurationKeyOrNull valueOfConfigurationKeyOrNull,
|
||||
@Org Predicate<ReferenceType> defaultSelector, Supplier<VCloudSession> sessionSupplier) {
|
||||
@Org Predicate<ReferenceType> defaultSelector, Supplier<VCloudSession> session) {
|
||||
this.selector = new OnlyReferenceTypeFirstWithNameMatchingConfigurationKeyOrDefault(checkNotNull(
|
||||
valueOfConfigurationKeyOrNull, "valueOfConfigurationKeyOrNull"), PROPERTY_VCLOUD_DEFAULT_ORG, checkNotNull(
|
||||
defaultSelector, "defaultSelector"));
|
||||
this.sessionSupplier = checkNotNull(sessionSupplier, "sessionSupplier");
|
||||
this.session = checkNotNull(session, "session");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Supplier<ReferenceType> apply(final String user) {
|
||||
return Suppliers.compose(new Function<VCloudSession, ReferenceType>() {
|
||||
|
||||
@Override
|
||||
public ReferenceType apply(VCloudSession session) {
|
||||
checkState(session != null, "could not retrieve Session at %s", user);
|
||||
return selector.apply(session.getOrgs().values());
|
||||
}
|
||||
|
||||
}, sessionSupplier);
|
||||
public ReferenceType get() {
|
||||
return selector.apply(session.get().getOrgs().values());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -26,10 +26,9 @@ import javax.inject.Inject;
|
|||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.rest.annotations.Identity;
|
||||
import org.jclouds.util.Suppliers2;
|
||||
import org.jclouds.vcloud.domain.Catalog;
|
||||
import org.jclouds.vcloud.domain.ReferenceType;
|
||||
import org.jclouds.vcloud.endpoints.Org;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Predicate;
|
||||
|
@ -41,24 +40,18 @@ import com.google.common.collect.ImmutableMap.Builder;
|
|||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Provides;
|
||||
import com.google.inject.TypeLiteral;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class DefaultVCloudReferencesModule extends AbstractModule {
|
||||
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
|
||||
}
|
||||
|
||||
@Provides
|
||||
@org.jclouds.vcloud.endpoints.Org
|
||||
@Singleton
|
||||
protected Supplier<ReferenceType> provideDefaultOrg(DefaultOrgForUser defaultOrgURIForUser,
|
||||
@Identity String user) {
|
||||
return defaultOrgURIForUser.apply(user);
|
||||
bind(new TypeLiteral<Supplier<ReferenceType>>() {
|
||||
}).annotatedWith(Org.class).to(DefaultOrgForUser.class);
|
||||
}
|
||||
|
||||
@Provides
|
||||
|
|
|
@ -49,6 +49,7 @@ import javax.ws.rs.core.HttpHeaders;
|
|||
import org.jclouds.Constants;
|
||||
import org.jclouds.crypto.Crypto;
|
||||
import org.jclouds.date.TimeStamp;
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.http.HttpException;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpRequestFilter;
|
||||
|
@ -57,10 +58,9 @@ import org.jclouds.http.internal.SignatureWire;
|
|||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.rest.RequestSigner;
|
||||
import org.jclouds.rest.annotations.ApiVersion;
|
||||
import org.jclouds.rest.annotations.Credential;
|
||||
import org.jclouds.rest.annotations.Identity;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Multimap;
|
||||
|
@ -83,8 +83,7 @@ public class FormSigner implements HttpRequestFilter, RequestSigner {
|
|||
|
||||
private final SignatureWire signatureWire;
|
||||
private final String apiVersion;
|
||||
private final String accessKey;
|
||||
private final String secretKey;
|
||||
private final Supplier<Credentials> creds;
|
||||
private final Provider<String> dateService;
|
||||
private final Crypto crypto;
|
||||
private final HttpUtils utils;
|
||||
|
@ -94,13 +93,12 @@ public class FormSigner implements HttpRequestFilter, RequestSigner {
|
|||
private Logger signatureLog = Logger.NULL;
|
||||
|
||||
@Inject
|
||||
public FormSigner(SignatureWire signatureWire, @ApiVersion String apiVersion, @Identity String accessKey,
|
||||
@Credential String secretKey, @TimeStamp Provider<String> dateService,
|
||||
Crypto crypto, HttpUtils utils) {
|
||||
public FormSigner(SignatureWire signatureWire, @ApiVersion String apiVersion,
|
||||
@org.jclouds.location.Provider Supplier<Credentials> creds, @TimeStamp Provider<String> dateService,
|
||||
Crypto crypto, HttpUtils utils) {
|
||||
this.signatureWire = signatureWire;
|
||||
this.apiVersion = apiVersion;
|
||||
this.accessKey = accessKey;
|
||||
this.secretKey = secretKey;
|
||||
this.creds = creds;
|
||||
this.dateService = dateService;
|
||||
this.crypto = crypto;
|
||||
this.utils = utils;
|
||||
|
@ -168,7 +166,7 @@ public class FormSigner implements HttpRequestFilter, RequestSigner {
|
|||
public String sign(String toSign) {
|
||||
String signature;
|
||||
try {
|
||||
ByteProcessor<byte[]> hmacSHA256 = asByteProcessor(crypto.hmacSHA256(secretKey.getBytes(UTF_8)));
|
||||
ByteProcessor<byte[]> hmacSHA256 = asByteProcessor(crypto.hmacSHA256(creds.get().credential.getBytes(UTF_8)));
|
||||
signature = base64().encode(readBytes(toInputStream(toSign), hmacSHA256));
|
||||
if (signatureWire.enabled())
|
||||
signatureWire.input(toInputStream(signature));
|
||||
|
@ -207,7 +205,7 @@ public class FormSigner implements HttpRequestFilter, RequestSigner {
|
|||
params.replaceValues(SIGNATURE_METHOD, ImmutableList.of("HmacSHA256"));
|
||||
params.replaceValues(SIGNATURE_VERSION, ImmutableList.of("2"));
|
||||
params.replaceValues(TIMESTAMP, ImmutableList.of(dateService.get()));
|
||||
params.replaceValues(AWS_ACCESS_KEY_ID, ImmutableList.of(accessKey));
|
||||
params.replaceValues(AWS_ACCESS_KEY_ID, ImmutableList.of(creds.get().identity));
|
||||
params.removeAll(SIGNATURE);
|
||||
}
|
||||
|
||||
|
|
|
@ -37,18 +37,18 @@ import javax.ws.rs.core.HttpHeaders;
|
|||
import org.jclouds.Constants;
|
||||
import org.jclouds.crypto.Crypto;
|
||||
import org.jclouds.date.TimeStamp;
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.http.HttpException;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpRequestFilter;
|
||||
import org.jclouds.http.HttpUtils;
|
||||
import org.jclouds.http.internal.SignatureWire;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.rest.annotations.Credential;
|
||||
import org.jclouds.rest.annotations.Identity;
|
||||
import org.jclouds.util.Strings2;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableMap.Builder;
|
||||
|
@ -68,8 +68,7 @@ public class SharedKeyLiteAuthentication implements HttpRequestFilter {
|
|||
private static final Collection<String> FIRST_HEADERS_TO_SIGN = ImmutableList.of(HttpHeaders.DATE);
|
||||
|
||||
private final SignatureWire signatureWire;
|
||||
private final String identity;
|
||||
private final byte[] key;
|
||||
private final Supplier<Credentials> creds;
|
||||
private final Provider<String> timeStampProvider;
|
||||
private final Crypto crypto;
|
||||
private final HttpUtils utils;
|
||||
|
@ -79,14 +78,13 @@ public class SharedKeyLiteAuthentication implements HttpRequestFilter {
|
|||
Logger signatureLog = Logger.NULL;
|
||||
|
||||
@Inject
|
||||
public SharedKeyLiteAuthentication(SignatureWire signatureWire, @Identity String identity,
|
||||
@Credential String encodedKey, @TimeStamp Provider<String> timeStampProvider,
|
||||
public SharedKeyLiteAuthentication(SignatureWire signatureWire,
|
||||
@org.jclouds.location.Provider Supplier<Credentials> creds, @TimeStamp Provider<String> timeStampProvider,
|
||||
Crypto crypto, HttpUtils utils) {
|
||||
this.crypto = crypto;
|
||||
this.utils = utils;
|
||||
this.signatureWire = signatureWire;
|
||||
this.identity = identity;
|
||||
this.key = base64().decode(encodedKey);
|
||||
this.creds = creds;
|
||||
this.timeStampProvider = timeStampProvider;
|
||||
}
|
||||
|
||||
|
@ -99,8 +97,9 @@ public class SharedKeyLiteAuthentication implements HttpRequestFilter {
|
|||
}
|
||||
|
||||
HttpRequest replaceAuthorizationHeader(HttpRequest request, String signature) {
|
||||
return request.toBuilder().replaceHeader(HttpHeaders.AUTHORIZATION, "SharedKeyLite " + identity + ":"
|
||||
+ signature).build();
|
||||
return request.toBuilder()
|
||||
.replaceHeader(HttpHeaders.AUTHORIZATION, "SharedKeyLite " + creds.get().identity + ":" + signature)
|
||||
.build();
|
||||
}
|
||||
|
||||
HttpRequest replaceDateHeader(HttpRequest request) {
|
||||
|
@ -143,7 +142,7 @@ public class SharedKeyLiteAuthentication implements HttpRequestFilter {
|
|||
|
||||
public String signString(String toSign) {
|
||||
try {
|
||||
ByteProcessor<byte[]> hmacSHA256 = asByteProcessor(crypto.hmacSHA256(key));
|
||||
ByteProcessor<byte[]> hmacSHA256 = asByteProcessor(crypto.hmacSHA256(base64().decode(creds.get().credential)));
|
||||
return base64().encode(readBytes(toInputStream(toSign), hmacSHA256));
|
||||
} catch (Exception e) {
|
||||
throw new HttpException("error signing request", e);
|
||||
|
@ -176,10 +175,9 @@ public class SharedKeyLiteAuthentication implements HttpRequestFilter {
|
|||
|
||||
@VisibleForTesting
|
||||
void appendCanonicalizedResource(HttpRequest request, StringBuilder toSign) {
|
||||
|
||||
// 1. Beginning with an empty string (""), append a forward slash (/), followed by the name of
|
||||
// the identity that owns the resource being accessed.
|
||||
toSign.append("/").append(identity);
|
||||
toSign.append("/").append(creds.get().identity);
|
||||
appendUriPath(request, toSign);
|
||||
}
|
||||
|
||||
|
|
|
@ -110,11 +110,11 @@ public class OpenStackAuthenticationModule extends AbstractModule {
|
|||
@Provides
|
||||
@Singleton
|
||||
protected Supplier<AuthenticationResponse> provideAuthenticationResponseSupplier(
|
||||
final LoadingCache<Credentials, AuthenticationResponse> cache, @Provider final Credentials creds) {
|
||||
final LoadingCache<Credentials, AuthenticationResponse> cache, @Provider final Supplier<Credentials> creds) {
|
||||
return new Supplier<AuthenticationResponse>() {
|
||||
@Override
|
||||
public AuthenticationResponse get() {
|
||||
return cache.getUnchecked(creds);
|
||||
return cache.getUnchecked(creds.get());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
*/
|
||||
package org.jclouds.openstack.keystone.v1_1.config;
|
||||
|
||||
import static com.google.common.base.Throwables.propagate;
|
||||
import static org.jclouds.rest.config.BinderUtils.bindHttpApi;
|
||||
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
@ -112,15 +111,11 @@ public class AuthenticationServiceModule extends AbstractModule {
|
|||
@Provides
|
||||
@Singleton
|
||||
protected Supplier<Auth> provideAuthSupplier(final LoadingCache<Credentials, Auth> cache,
|
||||
@Provider final Credentials creds) {
|
||||
@Provider final Supplier<Credentials> creds) {
|
||||
return new Supplier<Auth>() {
|
||||
@Override
|
||||
public Auth get() {
|
||||
try {
|
||||
return cache.get(creds);
|
||||
} catch (ExecutionException e) {
|
||||
throw propagate(e.getCause());
|
||||
}
|
||||
return cache.getUnchecked(creds.get());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
package org.jclouds.trmk.vcloud_0_8.config;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
import static org.jclouds.trmk.vcloud_0_8.reference.VCloudConstants.PROPERTY_VCLOUD_DEFAULT_ORG;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
@ -31,41 +30,31 @@ import org.jclouds.trmk.vcloud_0_8.domain.VCloudSession;
|
|||
import org.jclouds.trmk.vcloud_0_8.endpoints.Org;
|
||||
import org.jclouds.trmk.vcloud_0_8.suppliers.OnlyReferenceTypeFirstWithNameMatchingConfigurationKeyOrDefault;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.base.Suppliers;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Singleton
|
||||
public class DefaultOrgForUser implements Function<String, Supplier<ReferenceType>> {
|
||||
public class DefaultOrgForUser implements Supplier<ReferenceType> {
|
||||
|
||||
private final OnlyReferenceTypeFirstWithNameMatchingConfigurationKeyOrDefault selector;
|
||||
private final Supplier<VCloudSession> sessionSupplier;
|
||||
private final Supplier<VCloudSession> session;
|
||||
|
||||
@Inject
|
||||
public DefaultOrgForUser(ValueOfConfigurationKeyOrNull valueOfConfigurationKeyOrNull,
|
||||
@Org Predicate<ReferenceType> defaultSelector, Supplier<VCloudSession> sessionSupplier) {
|
||||
@Org Predicate<ReferenceType> defaultSelector, Supplier<VCloudSession> session) {
|
||||
this.selector = new OnlyReferenceTypeFirstWithNameMatchingConfigurationKeyOrDefault(checkNotNull(
|
||||
valueOfConfigurationKeyOrNull, "valueOfConfigurationKeyOrNull"), PROPERTY_VCLOUD_DEFAULT_ORG, checkNotNull(
|
||||
defaultSelector, "defaultSelector"));
|
||||
this.sessionSupplier = checkNotNull(sessionSupplier, "sessionSupplier");
|
||||
this.session = checkNotNull(session, "session");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Supplier<ReferenceType> apply(final String user) {
|
||||
return Suppliers.compose(new Function<VCloudSession, ReferenceType>() {
|
||||
|
||||
@Override
|
||||
public ReferenceType apply(VCloudSession session) {
|
||||
checkState(session != null, "could not retrieve Session at %s", user);
|
||||
return selector.apply(session.getOrgs().values());
|
||||
}
|
||||
|
||||
}, sessionSupplier);
|
||||
public ReferenceType get() {
|
||||
return selector.apply(session.get().getOrgs().values());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -23,10 +23,9 @@ import java.util.Map;
|
|||
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.rest.annotations.Identity;
|
||||
import org.jclouds.trmk.vcloud_0_8.domain.Catalog;
|
||||
import org.jclouds.trmk.vcloud_0_8.domain.ReferenceType;
|
||||
import org.jclouds.util.Suppliers2;
|
||||
import org.jclouds.trmk.vcloud_0_8.endpoints.Org;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Predicate;
|
||||
|
@ -38,6 +37,7 @@ import com.google.common.collect.ImmutableMap.Builder;
|
|||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Provides;
|
||||
import com.google.inject.TypeLiteral;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -47,15 +47,8 @@ public class DefaultVCloudReferencesModule extends AbstractModule {
|
|||
|
||||
@Override
|
||||
protected void configure() {
|
||||
|
||||
}
|
||||
|
||||
@Provides
|
||||
@org.jclouds.trmk.vcloud_0_8.endpoints.Org
|
||||
@Singleton
|
||||
protected Supplier<ReferenceType> provideDefaultOrg(DefaultOrgForUser defaultOrgURIForUser,
|
||||
@Identity String user) {
|
||||
return defaultOrgURIForUser.apply(user);
|
||||
bind(new TypeLiteral<Supplier<ReferenceType>>() {
|
||||
}).annotatedWith(Org.class).to(DefaultOrgForUser.class);
|
||||
}
|
||||
|
||||
@Provides
|
||||
|
|
|
@ -28,17 +28,17 @@ import javax.inject.Named;
|
|||
import javax.inject.Singleton;
|
||||
import javax.ws.rs.core.HttpHeaders;
|
||||
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.http.HttpException;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpRequestFilter;
|
||||
import org.jclouds.rest.annotations.Credential;
|
||||
import org.jclouds.rest.annotations.Identity;
|
||||
import org.jclouds.location.Provider;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.base.Supplier;
|
||||
|
||||
/**
|
||||
* Authenticates using Basic Authentication or a generated token from previous
|
||||
* API sessions.
|
||||
* Authenticates using Basic Authentication or a generated token from previous API sessions.
|
||||
*
|
||||
* @author Ignasi Barrera
|
||||
*/
|
||||
|
@ -47,23 +47,21 @@ public class AbiquoAuthentication implements HttpRequestFilter {
|
|||
/** The name of the authentication token. */
|
||||
public static final String AUTH_TOKEN_NAME = "auth";
|
||||
|
||||
protected String identity;
|
||||
|
||||
protected String credential;
|
||||
|
||||
protected Supplier<Credentials> creds;
|
||||
protected boolean credentialIsToken;
|
||||
|
||||
@Inject
|
||||
public AbiquoAuthentication(@Identity final String identity, @Credential final String credential,
|
||||
@Named(CREDENTIAL_IS_TOKEN) final String credentialIsToken) {
|
||||
this.identity = checkNotNull(identity, "identity");
|
||||
this.credential = checkNotNull(credential, "credential");
|
||||
this.credentialIsToken = Boolean.valueOf(credentialIsToken);
|
||||
public AbiquoAuthentication(@Provider Supplier<Credentials> creds,
|
||||
@Named(CREDENTIAL_IS_TOKEN) boolean credentialIsToken) {
|
||||
this.creds = checkNotNull(creds, "creds");
|
||||
this.credentialIsToken = credentialIsToken;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpRequest filter(final HttpRequest request) throws HttpException {
|
||||
String header = credentialIsToken ? tokenAuth(credential) : basic(identity, credential);
|
||||
Credentials currentCreds = checkNotNull(creds.get(), "credential supplier returned null");
|
||||
String header = credentialIsToken ? tokenAuth(currentCreds.credential) : basic(currentCreds.identity,
|
||||
currentCreds.credential);
|
||||
return request.toBuilder()
|
||||
.replaceHeader(credentialIsToken ? HttpHeaders.COOKIE : HttpHeaders.AUTHORIZATION, header).build();
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
package org.jclouds.abiquo.http.filters;
|
||||
|
||||
import static com.google.common.base.Suppliers.ofInstance;
|
||||
import static org.jclouds.http.filters.BasicAuthentication.basic;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertFalse;
|
||||
|
@ -29,6 +30,7 @@ import java.security.cert.CertificateException;
|
|||
|
||||
import javax.ws.rs.core.HttpHeaders;
|
||||
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
|
@ -43,7 +45,7 @@ public class AbiquoAuthenticationTest {
|
|||
public void testBasicAuthentication() throws NoSuchAlgorithmException, CertificateException {
|
||||
HttpRequest request = HttpRequest.builder().method("GET").endpoint(URI.create("http://foo")).build();
|
||||
|
||||
AbiquoAuthentication filter = new AbiquoAuthentication("identity", "credential", "false");
|
||||
AbiquoAuthentication filter = new AbiquoAuthentication(ofInstance(new Credentials("identity", "credential")), false);
|
||||
HttpRequest filtered = filter.filter(request);
|
||||
HttpRequest expected = request.toBuilder()
|
||||
.replaceHeader(HttpHeaders.AUTHORIZATION, basic("identity", "credential")).build();
|
||||
|
@ -56,7 +58,7 @@ public class AbiquoAuthenticationTest {
|
|||
public void testBasicAuthenticationWithoutIdentity() throws NoSuchAlgorithmException, CertificateException {
|
||||
HttpRequest request = HttpRequest.builder().method("GET").endpoint(URI.create("http://foo")).build();
|
||||
|
||||
AbiquoAuthentication filter = new AbiquoAuthentication(null, "credential", "false");
|
||||
AbiquoAuthentication filter = new AbiquoAuthentication(ofInstance(new Credentials(null, "credential")), false);
|
||||
filter.filter(request);
|
||||
}
|
||||
|
||||
|
@ -64,14 +66,15 @@ public class AbiquoAuthenticationTest {
|
|||
public void testBasicAuthenticationWithoutCredential() throws NoSuchAlgorithmException, CertificateException {
|
||||
HttpRequest request = HttpRequest.builder().method("GET").endpoint(URI.create("http://foo")).build();
|
||||
|
||||
AbiquoAuthentication filter = new AbiquoAuthentication("identity", null, "false");
|
||||
AbiquoAuthentication filter = new AbiquoAuthentication(ofInstance(new Credentials("identity", null)), false);
|
||||
filter.filter(request);
|
||||
}
|
||||
|
||||
public void testTokenAuthentication() throws NoSuchAlgorithmException, CertificateException {
|
||||
HttpRequest request = HttpRequest.builder().method("GET").endpoint(URI.create("http://foo")).build();
|
||||
|
||||
AbiquoAuthentication filter = new AbiquoAuthentication("token-identity", "token", "true");
|
||||
AbiquoAuthentication filter = new AbiquoAuthentication(ofInstance(new Credentials("token-identity", "token")),
|
||||
true);
|
||||
HttpRequest filtered = filter.filter(request);
|
||||
HttpRequest expected = request.toBuilder()
|
||||
.replaceHeader(HttpHeaders.COOKIE, AbiquoAuthentication.tokenAuth("token")).build();
|
||||
|
|
|
@ -18,25 +18,9 @@
|
|||
*/
|
||||
package org.jclouds.azure.management.config;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.security.KeyStore;
|
||||
import java.security.KeyStoreException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.cert.Certificate;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.CertificateFactory;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
import java.security.spec.KeySpec;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
import javax.net.ssl.SSLContext;
|
||||
|
||||
import org.jclouds.azure.management.AzureManagementApi;
|
||||
|
@ -53,19 +37,13 @@ import org.jclouds.azure.management.features.OperationApi;
|
|||
import org.jclouds.azure.management.features.OperationAsyncApi;
|
||||
import org.jclouds.azure.management.features.RoleApi;
|
||||
import org.jclouds.azure.management.features.RoleAsyncApi;
|
||||
import org.jclouds.azure.management.suppliers.KeyStoreSupplier;
|
||||
import org.jclouds.azure.management.suppliers.SSLContextWithKeysSupplier;
|
||||
import org.jclouds.crypto.Crypto;
|
||||
import org.jclouds.crypto.Pems;
|
||||
import org.jclouds.io.InputSuppliers;
|
||||
import org.jclouds.rest.ConfiguresRestClient;
|
||||
import org.jclouds.rest.annotations.Credential;
|
||||
import org.jclouds.rest.annotations.Identity;
|
||||
import org.jclouds.rest.config.RestClientModule;
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.inject.Provides;
|
||||
import com.google.inject.TypeLiteral;
|
||||
|
||||
/**
|
||||
|
@ -76,13 +54,12 @@ import com.google.inject.TypeLiteral;
|
|||
@ConfiguresRestClient
|
||||
public class AzureManagementRestClientModule extends RestClientModule<AzureManagementApi, AzureManagementAsyncApi> {
|
||||
public static final Map<Class<?>, Class<?>> DELEGATE_MAP = ImmutableMap.<Class<?>, Class<?>> builder()
|
||||
.put(LocationApi.class, LocationAsyncApi.class)
|
||||
.put(RoleApi.class, RoleAsyncApi.class)
|
||||
.put(HostedServiceApi.class, HostedServiceAsyncApi.class)
|
||||
.put(OSImageApi.class, OSImageAsyncApi.class)
|
||||
.put(OperationApi.class, OperationAsyncApi.class)
|
||||
.put(DiskApi.class, DiskAsyncApi.class)
|
||||
.build();
|
||||
.put(LocationApi.class, LocationAsyncApi.class)
|
||||
.put(RoleApi.class, RoleAsyncApi.class)
|
||||
.put(HostedServiceApi.class, HostedServiceAsyncApi.class)
|
||||
.put(OSImageApi.class, OSImageAsyncApi.class)
|
||||
.put(OperationApi.class, OperationAsyncApi.class)
|
||||
.put(DiskApi.class, DiskAsyncApi.class).build();
|
||||
|
||||
public AzureManagementRestClientModule() {
|
||||
super(DELEGATE_MAP);
|
||||
|
@ -94,59 +71,9 @@ public class AzureManagementRestClientModule extends RestClientModule<AzureManag
|
|||
bind(new TypeLiteral<Supplier<SSLContext>>() {
|
||||
}).to(new TypeLiteral<SSLContextWithKeysSupplier>() {
|
||||
});
|
||||
bind(new TypeLiteral<Supplier<KeyStore>>() {
|
||||
}).to(new TypeLiteral<KeyStoreSupplier>() {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO copied from FGCP, should be put in a common place
|
||||
*
|
||||
* @author Dies Koper
|
||||
*/
|
||||
@Provides
|
||||
@Singleton
|
||||
protected KeyStore provideKeyStore(Crypto crypto, @Identity String cert, @Credential String keyStorePassword)
|
||||
throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException,
|
||||
InvalidKeySpecException {
|
||||
KeyStore keyStore = KeyStore.getInstance("PKCS12");
|
||||
|
||||
File certFile = new File(checkNotNull(cert));
|
||||
if (certFile.isFile()) { // cert is path to pkcs12 file
|
||||
|
||||
keyStore.load(new FileInputStream(certFile), keyStorePassword.toCharArray());
|
||||
} else { // cert is PEM encoded, containing private key and certs
|
||||
|
||||
// split in private key and certs
|
||||
int privateKeyBeginIdx = cert.indexOf("-----BEGIN PRIVATE KEY");
|
||||
int privateKeyEndIdx = cert.indexOf("-----END PRIVATE KEY");
|
||||
String pemPrivateKey = cert.substring(privateKeyBeginIdx, privateKeyEndIdx + 26);
|
||||
|
||||
String pemCerts = "";
|
||||
int certsBeginIdx = 0;
|
||||
|
||||
do {
|
||||
certsBeginIdx = cert.indexOf("-----BEGIN CERTIFICATE", certsBeginIdx);
|
||||
|
||||
if (certsBeginIdx >= 0) {
|
||||
int certsEndIdx = cert.indexOf("-----END CERTIFICATE", certsBeginIdx) + 26;
|
||||
pemCerts += cert.substring(certsBeginIdx, certsEndIdx);
|
||||
certsBeginIdx = certsEndIdx;
|
||||
}
|
||||
} while (certsBeginIdx != -1);
|
||||
|
||||
// parse private key
|
||||
KeySpec keySpec = Pems.privateKeySpec(InputSuppliers.of(pemPrivateKey));
|
||||
PrivateKey privateKey = crypto.rsaKeyFactory().generatePrivate(keySpec);
|
||||
|
||||
// populate keystore with private key and certs
|
||||
CertificateFactory cf = CertificateFactory.getInstance("X.509");
|
||||
@SuppressWarnings("unchecked")
|
||||
Collection<Certificate> certs = (Collection<Certificate>) cf.generateCertificates(new ByteArrayInputStream(
|
||||
pemCerts.getBytes(Charsets.UTF_8)));
|
||||
keyStore.load(null);
|
||||
keyStore.setKeyEntry("dummy", privateKey, keyStorePassword.toCharArray(),
|
||||
certs.toArray(new java.security.cert.Certificate[0]));
|
||||
|
||||
}
|
||||
|
||||
return keyStore;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,130 @@
|
|||
/**
|
||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||
* contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. jclouds 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.azure.management.suppliers;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Throwables.propagate;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.security.KeyStore;
|
||||
import java.security.KeyStoreException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.cert.Certificate;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.CertificateFactory;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
import java.security.spec.KeySpec;
|
||||
import java.util.Collection;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.crypto.Crypto;
|
||||
import org.jclouds.crypto.Pems;
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.io.InputSuppliers;
|
||||
import org.jclouds.location.Provider;
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
import com.google.common.base.Supplier;
|
||||
|
||||
/**
|
||||
* TODO this code needs to be completely refactored. It needs to stop using KeyStore of at all possible and definitely
|
||||
* the local filesystem. Please look at oauth for examples on how to do this via PEMs.
|
||||
*/
|
||||
@Deprecated
|
||||
@Singleton
|
||||
public class KeyStoreSupplier implements Supplier<KeyStore> {
|
||||
private final Crypto crypto;
|
||||
private final Supplier<Credentials> creds;
|
||||
|
||||
@Inject
|
||||
KeyStoreSupplier(Crypto crypto, @Provider Supplier<Credentials> creds) {
|
||||
this.crypto = crypto;
|
||||
this.creds = creds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public KeyStore get() {
|
||||
Credentials currentCreds = checkNotNull(creds.get(), "credential supplier returned null");
|
||||
String cert = checkNotNull(currentCreds.identity, "credential supplier returned null identity (should be cert)");
|
||||
String keyStorePassword = checkNotNull(currentCreds.credential,
|
||||
"credential supplier returned null credential (should be keyStorePassword)");
|
||||
try {
|
||||
KeyStore keyStore = KeyStore.getInstance("PKCS12");
|
||||
|
||||
File certFile = new File(checkNotNull(cert));
|
||||
if (certFile.isFile()) { // cert is path to pkcs12 file
|
||||
|
||||
keyStore.load(new FileInputStream(certFile), keyStorePassword.toCharArray());
|
||||
} else { // cert is PEM encoded, containing private key and certs
|
||||
|
||||
// split in private key and certs
|
||||
int privateKeyBeginIdx = cert.indexOf("-----BEGIN PRIVATE KEY");
|
||||
int privateKeyEndIdx = cert.indexOf("-----END PRIVATE KEY");
|
||||
String pemPrivateKey = cert.substring(privateKeyBeginIdx, privateKeyEndIdx + 26);
|
||||
|
||||
String pemCerts = "";
|
||||
int certsBeginIdx = 0;
|
||||
|
||||
do {
|
||||
certsBeginIdx = cert.indexOf("-----BEGIN CERTIFICATE", certsBeginIdx);
|
||||
|
||||
if (certsBeginIdx >= 0) {
|
||||
int certsEndIdx = cert.indexOf("-----END CERTIFICATE", certsBeginIdx) + 26;
|
||||
pemCerts += cert.substring(certsBeginIdx, certsEndIdx);
|
||||
certsBeginIdx = certsEndIdx;
|
||||
}
|
||||
} while (certsBeginIdx != -1);
|
||||
|
||||
// parse private key
|
||||
KeySpec keySpec = Pems.privateKeySpec(InputSuppliers.of(pemPrivateKey));
|
||||
PrivateKey privateKey = crypto.rsaKeyFactory().generatePrivate(keySpec);
|
||||
|
||||
// populate keystore with private key and certs
|
||||
CertificateFactory cf = CertificateFactory.getInstance("X.509");
|
||||
@SuppressWarnings("unchecked")
|
||||
Collection<Certificate> certs = (Collection<Certificate>) cf.generateCertificates(new ByteArrayInputStream(
|
||||
pemCerts.getBytes(Charsets.UTF_8)));
|
||||
keyStore.load(null);
|
||||
keyStore.setKeyEntry("dummy", privateKey, keyStorePassword.toCharArray(),
|
||||
certs.toArray(new java.security.cert.Certificate[0]));
|
||||
|
||||
}
|
||||
return keyStore;
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw propagate(e);
|
||||
} catch (KeyStoreException e) {
|
||||
throw propagate(e);
|
||||
} catch (CertificateException e) {
|
||||
throw propagate(e);
|
||||
} catch (FileNotFoundException e) {
|
||||
throw propagate(e);
|
||||
} catch (IOException e) {
|
||||
throw propagate(e);
|
||||
} catch (InvalidKeySpecException e) {
|
||||
throw propagate(e);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -18,6 +18,9 @@
|
|||
*/
|
||||
package org.jclouds.azure.management.suppliers;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Throwables.propagate;
|
||||
|
||||
import java.security.KeyManagementException;
|
||||
import java.security.KeyStore;
|
||||
import java.security.KeyStoreException;
|
||||
|
@ -31,42 +34,52 @@ import javax.net.ssl.KeyManagerFactory;
|
|||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.TrustManager;
|
||||
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.http.HttpUtils;
|
||||
import org.jclouds.http.config.SSLModule.TrustAllCerts;
|
||||
import org.jclouds.rest.annotations.Credential;
|
||||
import org.jclouds.location.Provider;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
|
||||
/**
|
||||
*
|
||||
* TODO copied from FGCP, should be put in a common place
|
||||
*
|
||||
* SSLContext supplier with a configured key manager to enable client authentication with
|
||||
* certificates.
|
||||
*
|
||||
* @author Dies Koper
|
||||
* TODO this code needs to be completely refactored. It needs to stop using KeyStore of at all possible and definitely
|
||||
* the local filesystem. Please look at oauth for examples on how to do this via PEMs.
|
||||
*/
|
||||
@Deprecated
|
||||
@Singleton
|
||||
public class SSLContextWithKeysSupplier implements Supplier<SSLContext> {
|
||||
private SSLContext sc;
|
||||
private final Supplier<KeyStore> keyStore;
|
||||
private final TrustManager[] trustManager;
|
||||
private final Supplier<Credentials> creds;
|
||||
|
||||
@Inject
|
||||
SSLContextWithKeysSupplier(KeyStore keyStore, @Credential String keyStorePassword, HttpUtils utils,
|
||||
TrustAllCerts trustAllCerts) throws NoSuchAlgorithmException, KeyStoreException, UnrecoverableKeyException,
|
||||
KeyManagementException {
|
||||
|
||||
TrustManager[] trustManager = null;
|
||||
if (utils.trustAllCerts()) {
|
||||
trustManager = new TrustManager[] { trustAllCerts };
|
||||
}
|
||||
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
|
||||
kmf.init(keyStore, keyStorePassword.toCharArray());
|
||||
sc = SSLContext.getInstance("TLS");
|
||||
sc.init(kmf.getKeyManagers(), trustManager, new SecureRandom());
|
||||
SSLContextWithKeysSupplier(Supplier<KeyStore> keyStore, @Provider Supplier<Credentials> creds, HttpUtils utils,
|
||||
TrustAllCerts trustAllCerts) {
|
||||
this.keyStore = keyStore;
|
||||
this.trustManager = utils.trustAllCerts() ? new TrustManager[] { trustAllCerts } : null;
|
||||
this.creds = creds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SSLContext get() {
|
||||
return sc;
|
||||
Credentials currentCreds = checkNotNull(creds.get(), "credential supplier returned null");
|
||||
String keyStorePassword = checkNotNull(currentCreds.credential,
|
||||
"credential supplier returned null credential (should be keyStorePassword)");
|
||||
KeyManagerFactory kmf;
|
||||
try {
|
||||
kmf = KeyManagerFactory.getInstance("SunX509");
|
||||
kmf.init(keyStore.get(), keyStorePassword.toCharArray());
|
||||
SSLContext sc = SSLContext.getInstance("TLS");
|
||||
sc.init(kmf.getKeyManagers(), trustManager, new SecureRandom());
|
||||
return sc;
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw propagate(e);
|
||||
} catch (UnrecoverableKeyException e) {
|
||||
throw propagate(e);
|
||||
} catch (KeyStoreException e) {
|
||||
throw propagate(e);
|
||||
} catch (KeyManagementException e) {
|
||||
throw propagate(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,17 +18,21 @@
|
|||
*/
|
||||
package org.jclouds.snia.cdmi.v1.filters;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.net.HttpHeaders.AUTHORIZATION;
|
||||
import static org.jclouds.http.filters.BasicAuthentication.basic;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.crypto.Crypto;
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.http.HttpException;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpRequestFilter;
|
||||
import org.jclouds.http.filters.BasicAuthentication;
|
||||
import org.jclouds.location.Provider;
|
||||
import org.jclouds.rest.AuthorizationException;
|
||||
import org.jclouds.rest.annotations.Credential;
|
||||
import org.jclouds.rest.annotations.Identity;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
|
||||
/**
|
||||
* Uses Basic Authentication to sign the request, and adds the {@code TID} header.
|
||||
|
@ -39,23 +43,23 @@ import org.jclouds.rest.annotations.Identity;
|
|||
*/
|
||||
@Singleton
|
||||
public class BasicAuthenticationAndTenantId implements HttpRequestFilter {
|
||||
private final String tenantId;
|
||||
private final BasicAuthentication basicAuthentication;
|
||||
private final Supplier<Credentials> creds;
|
||||
|
||||
@Inject
|
||||
public BasicAuthenticationAndTenantId(@Identity String tenantIdAndUsername, @Credential String password,
|
||||
Crypto crypto) {
|
||||
if (tenantIdAndUsername.indexOf(':') == -1) {
|
||||
throw new AuthorizationException(String.format("Identity %s does not match format tenantId:username",
|
||||
tenantIdAndUsername), null);
|
||||
}
|
||||
this.tenantId = tenantIdAndUsername.substring(0, tenantIdAndUsername.indexOf(':'));
|
||||
String username = tenantIdAndUsername.substring(tenantIdAndUsername.indexOf(':') + 1);
|
||||
this.basicAuthentication = new BasicAuthentication(username, password, crypto);
|
||||
public BasicAuthenticationAndTenantId(@Provider Supplier<Credentials> creds) {
|
||||
this.creds = checkNotNull(creds, "creds");
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpRequest filter(HttpRequest request) throws HttpException {
|
||||
return basicAuthentication.filter(request.toBuilder().replaceHeader("TID", tenantId).build());
|
||||
Credentials currentCreds = checkNotNull(creds.get(), "credential supplier returned null");
|
||||
if (currentCreds.identity.indexOf(':') == -1) {
|
||||
throw new AuthorizationException(String.format("Identity %s does not match format tenantId:username",
|
||||
currentCreds.identity), null);
|
||||
}
|
||||
String tenantId = currentCreds.identity.substring(0, currentCreds.identity.indexOf(':'));
|
||||
String username = currentCreds.identity.substring(currentCreds.identity.indexOf(':') + 1);
|
||||
return request.toBuilder().replaceHeader("TID", tenantId)
|
||||
.replaceHeader(AUTHORIZATION, basic(username, currentCreds.credential)).build();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,31 +18,17 @@
|
|||
*/
|
||||
package org.jclouds.fujitsu.fgcp.compute;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.security.KeyStore;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.cert.Certificate;
|
||||
import java.security.cert.CertificateFactory;
|
||||
import java.security.spec.KeySpec;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Singleton;
|
||||
import javax.net.ssl.SSLContext;
|
||||
|
||||
import org.jclouds.crypto.Crypto;
|
||||
import org.jclouds.crypto.Pems;
|
||||
import org.jclouds.date.TimeStamp;
|
||||
import org.jclouds.fujitsu.fgcp.FGCPApi;
|
||||
import org.jclouds.fujitsu.fgcp.FGCPAsyncApi;
|
||||
import org.jclouds.fujitsu.fgcp.handlers.FGCPRetryIfNotProxyAuthenticationFailureHandler;
|
||||
import org.jclouds.fujitsu.fgcp.http.SSLContextWithKeysSupplier;
|
||||
import org.jclouds.fujitsu.fgcp.location.SystemAndNetworkSegmentToLocationSupplier;
|
||||
import org.jclouds.fujitsu.fgcp.services.AdditionalDiskApi;
|
||||
import org.jclouds.fujitsu.fgcp.services.AdditionalDiskAsyncApi;
|
||||
|
@ -64,22 +50,19 @@ import org.jclouds.fujitsu.fgcp.services.VirtualServerApi;
|
|||
import org.jclouds.fujitsu.fgcp.services.VirtualServerAsyncApi;
|
||||
import org.jclouds.fujitsu.fgcp.services.VirtualSystemApi;
|
||||
import org.jclouds.fujitsu.fgcp.services.VirtualSystemAsyncApi;
|
||||
import org.jclouds.fujitsu.fgcp.suppliers.KeyStoreSupplier;
|
||||
import org.jclouds.fujitsu.fgcp.suppliers.SSLContextWithKeysSupplier;
|
||||
import org.jclouds.fujitsu.fgcp.xml.FGCPJAXBParser;
|
||||
import org.jclouds.http.HttpRetryHandler;
|
||||
import org.jclouds.http.annotation.ClientError;
|
||||
import org.jclouds.io.InputSuppliers;
|
||||
import org.jclouds.location.suppliers.ImplicitLocationSupplier;
|
||||
import org.jclouds.location.suppliers.LocationsSupplier;
|
||||
import org.jclouds.location.suppliers.implicit.FirstNetwork;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.rest.AuthorizationException;
|
||||
import org.jclouds.rest.ConfiguresRestClient;
|
||||
import org.jclouds.rest.annotations.Credential;
|
||||
import org.jclouds.rest.annotations.Identity;
|
||||
import org.jclouds.rest.config.RestClientModule;
|
||||
import org.jclouds.xml.XMLParser;
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.inject.Provides;
|
||||
|
@ -100,7 +83,6 @@ public class FGCPRestClientModule extends
|
|||
|
||||
public static final Map<Class<?>, Class<?>> DELEGATE_MAP = ImmutableMap
|
||||
.<Class<?>, Class<?>> builder()
|
||||
//
|
||||
.put(VirtualDCApi.class, VirtualDCAsyncApi.class)
|
||||
.put(VirtualSystemApi.class, VirtualSystemAsyncApi.class)
|
||||
.put(VirtualServerApi.class, VirtualServerAsyncApi.class)
|
||||
|
@ -117,21 +99,11 @@ public class FGCPRestClientModule extends
|
|||
super(DELEGATE_MAP);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void bindErrorHandlers() {
|
||||
// bind(HttpErrorHandler.class).annotatedWith(Redirection.class).to(ParseAWSErrorFromXmlContent.class);
|
||||
// bind(HttpErrorHandler.class).annotatedWith(ClientError.class).to(ParseAWSErrorFromXmlContent.class);
|
||||
// bind(HttpErrorHandler.class).annotatedWith(ServerError.class).to(ParseAWSErrorFromXmlContent.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void installLocations() {
|
||||
super.installLocations();
|
||||
bind(ImplicitLocationSupplier.class).to(FirstNetwork.class).in(
|
||||
Scopes.SINGLETON);
|
||||
bind(LocationsSupplier.class).to(
|
||||
SystemAndNetworkSegmentToLocationSupplier.class).in(
|
||||
Scopes.SINGLETON);
|
||||
bind(ImplicitLocationSupplier.class).to(FirstNetwork.class).in(Scopes.SINGLETON);
|
||||
bind(LocationsSupplier.class).to(SystemAndNetworkSegmentToLocationSupplier.class).in(Scopes.SINGLETON);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -147,6 +119,9 @@ public class FGCPRestClientModule extends
|
|||
bind(new TypeLiteral<Supplier<SSLContext>>() {
|
||||
}).to(new TypeLiteral<SSLContextWithKeysSupplier>() {
|
||||
});
|
||||
bind(new TypeLiteral<Supplier<KeyStore>>() {
|
||||
}).to(new TypeLiteral<KeyStoreSupplier>() {
|
||||
});
|
||||
}
|
||||
|
||||
@Provides
|
||||
|
@ -154,223 +129,4 @@ public class FGCPRestClientModule extends
|
|||
protected Calendar provideCalendar() {
|
||||
return Calendar.getInstance();
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* @Provides
|
||||
*
|
||||
* @Singleton protected KeyStore
|
||||
* provideKeyStore(@Named(Constants.PROPERTY_IDENTITY) String
|
||||
* keyStoreFilename, @Named(Constants.PROPERTY_CREDENTIAL) String
|
||||
* keyStorePassword) throws KeyStoreException { KeyStore keyStore =
|
||||
* KeyStore.getInstance("pkcs12");
|
||||
*
|
||||
* try { FileInputStream is = new
|
||||
* FileInputStream(checkNotNull(keyStoreFilename,
|
||||
* Constants.PROPERTY_IDENTITY)); keyStore.load(is,
|
||||
* checkNotNull(keyStorePassword,
|
||||
* Constants.PROPERTY_CREDENTIAL).toCharArray()); } catch (Exception e) { //
|
||||
* expecting IOException, NoSuchAlgorithmException, CertificateException
|
||||
* logger.error(e, "Keystore could not be opened: %s", keyStoreFilename); }
|
||||
* return keyStore; }
|
||||
*
|
||||
* @Provides
|
||||
*
|
||||
* @Singleton protected PrivateKey provideKey(Provider<KeyStore>
|
||||
* keyStoreProvider, @Named(Constants.PROPERTY_CREDENTIAL) String
|
||||
* keyPassword) throws KeyStoreException, NoSuchAlgorithmException,
|
||||
* UnrecoverableKeyException { KeyStore keyStore = keyStoreProvider.get();
|
||||
* if (keyStore == null) return null;
|
||||
*
|
||||
* // retrieving 1st alias in keystore as expecting only one String alias =
|
||||
* checkNotNull(keyStore.aliases().nextElement(),
|
||||
* "first alias in keystore"); return (PrivateKey) keyStore.getKey(alias,
|
||||
* checkNotNull(keyPassword, Constants.PROPERTY_CREDENTIAL).toCharArray());
|
||||
* }
|
||||
*/
|
||||
/*
|
||||
* maybe we can provide two authentication methods:
|
||||
*
|
||||
* 1. same as DeltaCloud: User passes a folder name as identity and cert
|
||||
* password as credential Note: pass relative path (e.g. cert's path:
|
||||
* c:\jclouds\certs\dkoper\UserCert.p12: user passes 'dkoper': provider
|
||||
* impl. finds it under e.g. $USER_DIR or $CURRENT_DIR or pass absolute path
|
||||
* 2. no file access for GAE: User passes cert in PEM format (converted from
|
||||
* UserCert.p12 using openssl?) as identity and cert password as credential
|
||||
*/
|
||||
@Provides
|
||||
@Singleton
|
||||
protected KeyStore provideKeyStore(Crypto crypto, @Identity String cert,
|
||||
@Credential String keyStorePassword) {
|
||||
KeyStore keyStore = null;
|
||||
try {
|
||||
keyStore = KeyStore.getInstance("PKCS12");
|
||||
|
||||
// System.out.println("cert: " + cert);
|
||||
// System.out.println("pwd : " + keyStorePassword);
|
||||
File certFile = new File(checkNotNull(cert));
|
||||
if (certFile.isFile()) { // cert is path to pkcs12 file
|
||||
|
||||
keyStore.load(new FileInputStream(certFile),
|
||||
keyStorePassword.toCharArray());
|
||||
} else { // cert is PEM encoded, containing private key and certs
|
||||
|
||||
// System.out.println("cert:\n" + cert);
|
||||
// split in private key and certs
|
||||
int privateKeyBeginIdx = cert.indexOf("-----BEGIN PRIVATE KEY");
|
||||
int privateKeyEndIdx = cert.indexOf("-----END PRIVATE KEY");
|
||||
String pemPrivateKey = cert.substring(privateKeyBeginIdx,
|
||||
privateKeyEndIdx + 26);
|
||||
// System.out.println("***************");
|
||||
// System.out.println("pemPrivateKey:\n" + pemPrivateKey);
|
||||
// System.out.println("***************");
|
||||
|
||||
String pemCerts = "";
|
||||
int certsBeginIdx = 0;
|
||||
|
||||
do {
|
||||
certsBeginIdx = cert.indexOf("-----BEGIN CERTIFICATE",
|
||||
certsBeginIdx);
|
||||
// System.out.println("begin:" + certsBeginIdx);
|
||||
|
||||
if (certsBeginIdx >= 0) {
|
||||
int certsEndIdx = cert.indexOf("-----END CERTIFICATE",
|
||||
certsBeginIdx) + 26;
|
||||
// System.out.println("end :" + certsEndIdx);
|
||||
pemCerts += cert.substring(certsBeginIdx, certsEndIdx);
|
||||
certsBeginIdx = certsEndIdx;
|
||||
}
|
||||
} while (certsBeginIdx != -1);
|
||||
// System.out.println("***************");
|
||||
// System.out.println("pemCerts:\n" + pemCerts);
|
||||
// System.out.println("***************");
|
||||
|
||||
/*
|
||||
* String pemCerts = "-----BEGIN "; Splitter pemSplitter =
|
||||
* Splitter.on("-----BEGIN ");
|
||||
*
|
||||
* for (String part : pemSplitter.split(cert)) {
|
||||
* System.out.println("***************");
|
||||
* System.out.println("Part:\n" + part);
|
||||
* System.out.println("***************");
|
||||
*
|
||||
* if (part.startsWith("PRIVATE KEY")
|
||||
*/
|
||||
/* || part.startsWith("RSA PRIVATE KEY)" *//*
|
||||
* ) {
|
||||
*
|
||||
* int certEndIdx =
|
||||
* part.lastIndexOf
|
||||
* ("-----END");
|
||||
* pemPrivateKey +=
|
||||
* part.substring(0,
|
||||
* certEndIdx + 26);
|
||||
* // take up to next
|
||||
* "-----" (i.e.
|
||||
* "-----END") //
|
||||
* Splitter
|
||||
* keySplitter =
|
||||
* Splitter
|
||||
* .on("-----").
|
||||
* omitEmptyStrings
|
||||
* ().trimResults();
|
||||
* //
|
||||
* Iterator<String>
|
||||
* iter =
|
||||
* keySplitter.
|
||||
* split(part
|
||||
* ).iterator(); //
|
||||
* String keyName =
|
||||
* iter.next() +
|
||||
* "-----\n"; //
|
||||
* pemPrivateKey +=
|
||||
* keyName; ////
|
||||
* System.out
|
||||
* .println
|
||||
* ("Skipping: '" +
|
||||
* iter.next() +
|
||||
* "'"); //
|
||||
* pemPrivateKey +=
|
||||
* iter.next(); //
|
||||
* pemPrivateKey +=
|
||||
* "\n-----END " +
|
||||
* keyName;
|
||||
* System.out.println
|
||||
* (
|
||||
* "/////////////////"
|
||||
* );
|
||||
* System.out.println
|
||||
* (
|
||||
* "pemPrivateKey:\n"
|
||||
* + pemPrivateKey);
|
||||
* System
|
||||
* .out.println(
|
||||
* "/////////////////"
|
||||
* ); } else if
|
||||
* (part.startsWith
|
||||
* ("CERTIFICATE")) {
|
||||
*
|
||||
* // take up to next
|
||||
* "-----" (i.e.
|
||||
* "-----END") // or
|
||||
* take up to last
|
||||
* END CERTIFICATE?
|
||||
* int certEndIdx =
|
||||
* part.lastIndexOf (
|
||||
* "----- END CERTIFICATE"
|
||||
* ); // pemCerts +=
|
||||
* part. // Splitter
|
||||
* keySplitter =
|
||||
* Splitter
|
||||
* .on("-----").
|
||||
* omitEmptyStrings
|
||||
* (); // pemCerts +=
|
||||
* keySplitter
|
||||
* .split(part)
|
||||
* .iterator
|
||||
* ().next(); //
|
||||
* pemCerts +=
|
||||
* "-----BEGIN "; }
|
||||
* else { // ignore
|
||||
* the fluff in
|
||||
* between (Bag
|
||||
* Attributes, etc.)
|
||||
* } }
|
||||
*/
|
||||
|
||||
// parse private key
|
||||
KeySpec keySpec = Pems.privateKeySpec(InputSuppliers
|
||||
.of(pemPrivateKey));
|
||||
PrivateKey privateKey = crypto.rsaKeyFactory().generatePrivate(
|
||||
keySpec);
|
||||
|
||||
// populate keystore with private key and certs
|
||||
CertificateFactory cf = CertificateFactory.getInstance("X.509");
|
||||
@SuppressWarnings("unchecked")
|
||||
Collection<Certificate> certs = (Collection<Certificate>) cf
|
||||
.generateCertificates(new ByteArrayInputStream(pemCerts
|
||||
.getBytes(Charsets.UTF_8)));
|
||||
keyStore.load(null);
|
||||
keyStore.setKeyEntry("dummy", privateKey,
|
||||
keyStorePassword.toCharArray(),
|
||||
certs.toArray(new java.security.cert.Certificate[0]));
|
||||
|
||||
// System.out.println("private key: " + privateKey.getFormat() +
|
||||
// "; "
|
||||
// + privateKey.getAlgorithm() + "; class: " +
|
||||
// privateKey.getClass().getName());// + "; " + new
|
||||
// String(privateKey.getEncoded()));
|
||||
|
||||
}
|
||||
} catch (Exception e) {
|
||||
/*
|
||||
* KeyStoreException, IOException, NoSuchAlgorithmException,
|
||||
* CertificateException, InvalidKeySpecException
|
||||
*/
|
||||
throw new AuthorizationException("Error loading certificate", e);
|
||||
}
|
||||
|
||||
return keyStore;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ package org.jclouds.fujitsu.fgcp.filters;
|
|||
|
||||
import static com.google.common.base.Charsets.UTF_8;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Throwables.propagate;
|
||||
import static com.google.common.io.BaseEncoding.base64;
|
||||
import static org.jclouds.http.utils.Queries.queryParser;
|
||||
|
||||
|
@ -33,6 +34,7 @@ import java.security.SignatureException;
|
|||
import java.security.UnrecoverableKeyException;
|
||||
import java.util.Calendar;
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Inject;
|
||||
|
@ -45,6 +47,7 @@ import javax.ws.rs.core.MediaType;
|
|||
|
||||
import org.jclouds.Constants;
|
||||
import org.jclouds.date.TimeStamp;
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.fujitsu.fgcp.reference.RequestParameters;
|
||||
import org.jclouds.http.HttpException;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
|
@ -54,14 +57,16 @@ import org.jclouds.http.internal.SignatureWire;
|
|||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.rest.RequestSigner;
|
||||
import org.jclouds.rest.annotations.ApiVersion;
|
||||
import org.jclouds.rest.annotations.Credential;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
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.collect.Multimap;
|
||||
|
||||
/**
|
||||
* Generates and signs the access key id and adds the mandatory http header and
|
||||
* request parameters to the request.
|
||||
* Generates and signs the access key id and adds the mandatory http header and request parameters to the request.
|
||||
*
|
||||
* @author Dies Koper
|
||||
*/
|
||||
|
@ -71,37 +76,65 @@ public class RequestAuthenticator implements HttpRequestFilter, RequestSigner {
|
|||
@Resource
|
||||
@Named(Constants.LOGGER_SIGNATURE)
|
||||
private Logger signatureLog = Logger.NULL;
|
||||
|
||||
private final Supplier<Credentials> creds;
|
||||
private final LoadingCache<Credentials, Signature> signerCache;
|
||||
private final Provider<Calendar> calendarProvider;
|
||||
private final HttpUtils utils;
|
||||
private final String apiVersion;
|
||||
|
||||
final Provider<Calendar> calendarProvider;
|
||||
final Signature signer;
|
||||
final String apiVersion;
|
||||
|
||||
public String signatureVersion = "1.0";
|
||||
public String signatureMethod = "SHA1withRSA";
|
||||
|
||||
private HttpUtils utils;
|
||||
private final static String signatureVersion = "1.0";
|
||||
private final static String signatureMethod = "SHA1withRSA";
|
||||
|
||||
@Inject
|
||||
public RequestAuthenticator(@TimeStamp Provider<Calendar> calendarProvider, Provider<KeyStore> keyStoreProvider,
|
||||
@Credential String keyPassword, HttpUtils utils, SignatureWire signatureWire, @ApiVersion String apiVersion)
|
||||
throws NoSuchAlgorithmException, InvalidKeyException, KeyStoreException, UnrecoverableKeyException {
|
||||
public RequestAuthenticator(@TimeStamp Provider<Calendar> calendarProvider, SignatureForCredentials loader,
|
||||
@org.jclouds.location.Provider Supplier<Credentials> creds, HttpUtils utils, SignatureWire signatureWire,
|
||||
@ApiVersion String apiVersion) {
|
||||
this.calendarProvider = checkNotNull(calendarProvider);
|
||||
this.creds = checkNotNull(creds, "creds");
|
||||
// throw out the signature related to old keys
|
||||
this.signerCache = CacheBuilder.newBuilder().maximumSize(2).build(checkNotNull(loader, "loader"));
|
||||
this.utils = checkNotNull(utils, "utils");
|
||||
this.apiVersion = checkNotNull(apiVersion, "apiVersion");
|
||||
}
|
||||
|
||||
signer = Signature.getInstance(signatureMethod);
|
||||
/**
|
||||
* it is relatively expensive to create a new signing key. cache the relationship between current credentials so that
|
||||
* the signer is only recalculated once.
|
||||
*/
|
||||
private static class SignatureForCredentials extends CacheLoader<Credentials, Signature> {
|
||||
private final Supplier<KeyStore> keyStore;
|
||||
|
||||
KeyStore keyStore = checkNotNull(keyStoreProvider).get();
|
||||
String alias = keyStore.aliases().nextElement(); // there should be only one private key
|
||||
PrivateKey privateKey = (PrivateKey) keyStore.getKey(alias,
|
||||
keyPassword.toCharArray());
|
||||
@Inject
|
||||
public SignatureForCredentials(Supplier<KeyStore> keyStore) {
|
||||
this.keyStore = checkNotNull(keyStore, "keyStore");
|
||||
}
|
||||
|
||||
signer.initSign(privateKey);
|
||||
@Override
|
||||
public Signature load(Credentials in) {
|
||||
String keyPassword = checkNotNull(in.credential,
|
||||
"credential supplier returned null for credential (keyPassword)");
|
||||
try {
|
||||
Signature signer = Signature.getInstance(signatureMethod);
|
||||
KeyStore keyStore = checkNotNull(this.keyStore.get(), "keyStore");
|
||||
String alias = keyStore.aliases().nextElement(); // there should be only one private key
|
||||
PrivateKey privateKey = (PrivateKey) keyStore.getKey(alias, keyPassword.toCharArray());
|
||||
signer.initSign(privateKey);
|
||||
return signer;
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw propagate(e);
|
||||
} catch (KeyStoreException e) {
|
||||
throw propagate(e);
|
||||
} catch (UnrecoverableKeyException e) {
|
||||
throw propagate(e);
|
||||
} catch (InvalidKeyException e) {
|
||||
throw propagate(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public HttpRequest filter(HttpRequest request) throws HttpException {
|
||||
checkNotNull(request, "request must be present");
|
||||
|
||||
utils.logRequest(signatureLog, request, ">>");
|
||||
|
||||
// create accesskeyid
|
||||
|
@ -109,8 +142,7 @@ public class RequestAuthenticator implements HttpRequestFilter, RequestSigner {
|
|||
String signature = sign(accessKeyId);
|
||||
|
||||
// only "en" and "ja" are allowed
|
||||
String lang = Locale.JAPANESE.getLanguage().equals(
|
||||
Locale.getDefault().getLanguage()) ? Locale.JAPANESE
|
||||
String lang = Locale.JAPANESE.getLanguage().equals(Locale.getDefault().getLanguage()) ? Locale.JAPANESE
|
||||
.getLanguage() : Locale.ENGLISH.getLanguage();
|
||||
|
||||
if (HttpMethod.GET.equals(request.getMethod())) {
|
||||
|
@ -126,24 +158,18 @@ public class RequestAuthenticator implements HttpRequestFilter, RequestSigner {
|
|||
} else {
|
||||
|
||||
String payload = request.getPayload().getRawContent().toString();
|
||||
payload = createXmlElementWithValue(payload,
|
||||
RequestParameters.VERSION, apiVersion);
|
||||
payload = createXmlElementWithValue(payload,
|
||||
RequestParameters.LOCALE, lang);
|
||||
payload = createXmlElementWithValue(payload,
|
||||
RequestParameters.ACCESS_KEY_ID, accessKeyId);
|
||||
payload = createXmlElementWithValue(payload,
|
||||
RequestParameters.SIGNATURE, signature);
|
||||
payload = createXmlElementWithValue(payload, RequestParameters.VERSION, apiVersion);
|
||||
payload = createXmlElementWithValue(payload, RequestParameters.LOCALE, lang);
|
||||
payload = createXmlElementWithValue(payload, RequestParameters.ACCESS_KEY_ID, accessKeyId);
|
||||
payload = createXmlElementWithValue(payload, RequestParameters.SIGNATURE, signature);
|
||||
|
||||
// ensure there are no other query params left
|
||||
request.setPayload(payload);
|
||||
request.getPayload().getContentMetadata()
|
||||
.setContentType(MediaType.TEXT_XML);
|
||||
request.getPayload().getContentMetadata().setContentType(MediaType.TEXT_XML);
|
||||
}
|
||||
|
||||
// may need to do this elsewhere (see ConvertToGaeRequest)
|
||||
HttpRequest filteredRequest = request.toBuilder()
|
||||
.replaceHeader(HttpHeaders.USER_AGENT, "OViSS-API-CLIENT")
|
||||
HttpRequest filteredRequest = request.toBuilder().replaceHeader(HttpHeaders.USER_AGENT, "OViSS-API-CLIENT")
|
||||
.build();
|
||||
|
||||
utils.logRequest(signatureLog, filteredRequest, ">>->");
|
||||
|
@ -158,27 +184,18 @@ public class RequestAuthenticator implements HttpRequestFilter, RequestSigner {
|
|||
return payload.replace(startTag + endTag, startTag + value + endTag);
|
||||
}
|
||||
|
||||
/*
|
||||
* HttpRequest setPayload(HttpRequest request, Multimap<String, String>
|
||||
* decodedParams) {
|
||||
* request.setPayload(ModifyRequest.makeQueryLine(decodedParams, null)); //
|
||||
* request.getPayload().getContentMetadata().setContentType(
|
||||
* "application/x-www-form-urlencoded"); return request; }
|
||||
*/
|
||||
|
||||
@VisibleForTesting
|
||||
public String sign(String stringToSign) {
|
||||
String signed;
|
||||
|
||||
try {
|
||||
Signature signer = signerCache.get(checkNotNull(creds.get(), "credential supplier returned null"));
|
||||
signer.update(stringToSign.getBytes(UTF_8));
|
||||
signed = base64().encode(signer.sign());
|
||||
} catch (SignatureException e) {
|
||||
throw new HttpException("error signing request", e);
|
||||
} catch (ExecutionException e) {
|
||||
throw new HttpException("couldn't load key for signing request", e);
|
||||
}
|
||||
// if (signatureWire.enabled())
|
||||
// signatureWire.input(Strings2.toInputStream(signed));
|
||||
|
||||
return signed;
|
||||
}
|
||||
|
||||
|
@ -188,8 +205,7 @@ public class RequestAuthenticator implements HttpRequestFilter, RequestSigner {
|
|||
String timezone = cal.getTimeZone().getDisplayName(Locale.ENGLISH);
|
||||
String expires = String.valueOf(cal.getTime().getTime());
|
||||
|
||||
String signatureData = String.format("%s&%s&%s&%s", timezone, expires,
|
||||
signatureVersion, signatureMethod);
|
||||
String signatureData = String.format("%s&%s&%s&%s", timezone, expires, signatureVersion, signatureMethod);
|
||||
String accessKeyId = base64().encode(signatureData.getBytes(UTF_8));
|
||||
return accessKeyId.replace("\n", "\r\n");
|
||||
}
|
||||
|
|
|
@ -1,71 +0,0 @@
|
|||
/**
|
||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||
* contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. jclouds 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.fujitsu.fgcp.http;
|
||||
|
||||
import java.security.KeyManagementException;
|
||||
import java.security.KeyStore;
|
||||
import java.security.KeyStoreException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.UnrecoverableKeyException;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import javax.net.ssl.KeyManagerFactory;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.TrustManager;
|
||||
|
||||
import org.jclouds.http.HttpUtils;
|
||||
import org.jclouds.http.config.SSLModule.TrustAllCerts;
|
||||
import org.jclouds.rest.annotations.Credential;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
|
||||
/**
|
||||
* SSLContext supplier with a configured key manager to enable client
|
||||
* authentication with certificates.
|
||||
*
|
||||
* @author Dies Koper
|
||||
*/
|
||||
@Singleton
|
||||
public class SSLContextWithKeysSupplier implements Supplier<SSLContext> {
|
||||
private SSLContext sc;
|
||||
|
||||
@Inject
|
||||
SSLContextWithKeysSupplier(KeyStore keyStore,
|
||||
@Credential String keyStorePassword, HttpUtils utils,
|
||||
TrustAllCerts trustAllCerts) throws NoSuchAlgorithmException,
|
||||
KeyStoreException, UnrecoverableKeyException,
|
||||
KeyManagementException {
|
||||
|
||||
TrustManager[] trustManager = null;
|
||||
if (utils.trustAllCerts()) {
|
||||
trustManager = new TrustManager[] { trustAllCerts };
|
||||
}
|
||||
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
|
||||
kmf.init(keyStore, keyStorePassword.toCharArray());
|
||||
sc = SSLContext.getInstance("TLS");
|
||||
sc.init(kmf.getKeyManagers(), trustManager, new SecureRandom());
|
||||
}
|
||||
|
||||
@Override
|
||||
public SSLContext get() {
|
||||
return sc;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,130 @@
|
|||
/**
|
||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||
* contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. jclouds 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.fujitsu.fgcp.suppliers;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Throwables.propagate;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.security.KeyStore;
|
||||
import java.security.KeyStoreException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.cert.Certificate;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.CertificateFactory;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
import java.security.spec.KeySpec;
|
||||
import java.util.Collection;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.crypto.Crypto;
|
||||
import org.jclouds.crypto.Pems;
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.io.InputSuppliers;
|
||||
import org.jclouds.location.Provider;
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
import com.google.common.base.Supplier;
|
||||
|
||||
/**
|
||||
* TODO this code needs to be completely refactored. It needs to stop using KeyStore of at all possible and definitely
|
||||
* the local filesystem. Please look at oauth for examples on how to do this via PEMs.
|
||||
*/
|
||||
@Deprecated
|
||||
@Singleton
|
||||
public class KeyStoreSupplier implements Supplier<KeyStore> {
|
||||
private final Crypto crypto;
|
||||
private final Supplier<Credentials> creds;
|
||||
|
||||
@Inject
|
||||
public KeyStoreSupplier(Crypto crypto, @Provider Supplier<Credentials> creds) {
|
||||
this.crypto = crypto;
|
||||
this.creds = creds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public KeyStore get() {
|
||||
Credentials currentCreds = checkNotNull(creds.get(), "credential supplier returned null");
|
||||
String cert = checkNotNull(currentCreds.identity, "credential supplier returned null identity (should be cert)");
|
||||
String keyStorePassword = checkNotNull(currentCreds.credential,
|
||||
"credential supplier returned null credential (should be keyStorePassword)");
|
||||
try {
|
||||
KeyStore keyStore = KeyStore.getInstance("PKCS12");
|
||||
|
||||
File certFile = new File(checkNotNull(cert));
|
||||
if (certFile.isFile()) { // cert is path to pkcs12 file
|
||||
|
||||
keyStore.load(new FileInputStream(certFile), keyStorePassword.toCharArray());
|
||||
} else { // cert is PEM encoded, containing private key and certs
|
||||
|
||||
// split in private key and certs
|
||||
int privateKeyBeginIdx = cert.indexOf("-----BEGIN PRIVATE KEY");
|
||||
int privateKeyEndIdx = cert.indexOf("-----END PRIVATE KEY");
|
||||
String pemPrivateKey = cert.substring(privateKeyBeginIdx, privateKeyEndIdx + 26);
|
||||
|
||||
String pemCerts = "";
|
||||
int certsBeginIdx = 0;
|
||||
|
||||
do {
|
||||
certsBeginIdx = cert.indexOf("-----BEGIN CERTIFICATE", certsBeginIdx);
|
||||
|
||||
if (certsBeginIdx >= 0) {
|
||||
int certsEndIdx = cert.indexOf("-----END CERTIFICATE", certsBeginIdx) + 26;
|
||||
pemCerts += cert.substring(certsBeginIdx, certsEndIdx);
|
||||
certsBeginIdx = certsEndIdx;
|
||||
}
|
||||
} while (certsBeginIdx != -1);
|
||||
|
||||
// parse private key
|
||||
KeySpec keySpec = Pems.privateKeySpec(InputSuppliers.of(pemPrivateKey));
|
||||
PrivateKey privateKey = crypto.rsaKeyFactory().generatePrivate(keySpec);
|
||||
|
||||
// populate keystore with private key and certs
|
||||
CertificateFactory cf = CertificateFactory.getInstance("X.509");
|
||||
@SuppressWarnings("unchecked")
|
||||
Collection<Certificate> certs = (Collection<Certificate>) cf.generateCertificates(new ByteArrayInputStream(
|
||||
pemCerts.getBytes(Charsets.UTF_8)));
|
||||
keyStore.load(null);
|
||||
keyStore.setKeyEntry("dummy", privateKey, keyStorePassword.toCharArray(),
|
||||
certs.toArray(new java.security.cert.Certificate[0]));
|
||||
|
||||
}
|
||||
return keyStore;
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw propagate(e);
|
||||
} catch (KeyStoreException e) {
|
||||
throw propagate(e);
|
||||
} catch (CertificateException e) {
|
||||
throw propagate(e);
|
||||
} catch (FileNotFoundException e) {
|
||||
throw propagate(e);
|
||||
} catch (IOException e) {
|
||||
throw propagate(e);
|
||||
} catch (InvalidKeySpecException e) {
|
||||
throw propagate(e);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
/**
|
||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||
* contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. jclouds 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.fujitsu.fgcp.suppliers;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Throwables.propagate;
|
||||
|
||||
import java.security.KeyManagementException;
|
||||
import java.security.KeyStore;
|
||||
import java.security.KeyStoreException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.UnrecoverableKeyException;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import javax.net.ssl.KeyManagerFactory;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.TrustManager;
|
||||
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.http.HttpUtils;
|
||||
import org.jclouds.http.config.SSLModule.TrustAllCerts;
|
||||
import org.jclouds.location.Provider;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
|
||||
/**
|
||||
* TODO this code needs to be completely refactored. It needs to stop using KeyStore of at all possible and definitely
|
||||
* the local filesystem. Please look at oauth for examples on how to do this via PEMs.
|
||||
*/
|
||||
@Deprecated
|
||||
@Singleton
|
||||
public class SSLContextWithKeysSupplier implements Supplier<SSLContext> {
|
||||
private final Supplier<KeyStore> keyStore;
|
||||
private final TrustManager[] trustManager;
|
||||
private final Supplier<Credentials> creds;
|
||||
|
||||
@Inject
|
||||
SSLContextWithKeysSupplier(Supplier<KeyStore> keyStore, @Provider Supplier<Credentials> creds, HttpUtils utils,
|
||||
TrustAllCerts trustAllCerts) {
|
||||
this.keyStore = keyStore;
|
||||
this.trustManager = utils.trustAllCerts() ? new TrustManager[] { trustAllCerts } : null;
|
||||
this.creds = creds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SSLContext get() {
|
||||
Credentials currentCreds = checkNotNull(creds.get(), "credential supplier returned null");
|
||||
String keyStorePassword = checkNotNull(currentCreds.credential,
|
||||
"credential supplier returned null credential (should be keyStorePassword)");
|
||||
KeyManagerFactory kmf;
|
||||
try {
|
||||
kmf = KeyManagerFactory.getInstance("SunX509");
|
||||
kmf.init(keyStore.get(), keyStorePassword.toCharArray());
|
||||
SSLContext sc = SSLContext.getInstance("TLS");
|
||||
sc.init(kmf.getKeyManagers(), trustManager, new SecureRandom());
|
||||
return sc;
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw propagate(e);
|
||||
} catch (UnrecoverableKeyException e) {
|
||||
throw propagate(e);
|
||||
} catch (KeyStoreException e) {
|
||||
throw propagate(e);
|
||||
} catch (KeyManagementException e) {
|
||||
throw propagate(e);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -29,9 +29,12 @@ import java.security.cert.CertificateException;
|
|||
import java.security.spec.InvalidKeySpecException;
|
||||
|
||||
import org.jclouds.crypto.Crypto;
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.fujitsu.fgcp.suppliers.KeyStoreSupplier;
|
||||
import org.testng.annotations.BeforeTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.base.Suppliers;
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
|
||||
|
@ -56,40 +59,37 @@ public class FGCPRestClientModuleTest {
|
|||
module = i.getInstance(FGCPRestClientModule.class);
|
||||
}
|
||||
|
||||
public void testKeyStoreAsPkcs12() throws IOException, InvalidKeySpecException, NoSuchAlgorithmException, KeyStoreException, CertificateException {
|
||||
public void testKeyStoreAsPkcs12() throws IOException, InvalidKeySpecException, NoSuchAlgorithmException,
|
||||
KeyStoreException, CertificateException {
|
||||
assertNotNull(crypto);
|
||||
assertNotNull(module);
|
||||
|
||||
// self-signed dummy cert:
|
||||
// keytool -genkey -alias test-fgcp -keyalg RSA -keysize 1024 -validity 5475 -dname "CN=localhost" -keystore jclouds-test-fgcp.p12 -storepass jcloudsjclouds -storetype pkcs12
|
||||
// keytool -genkey -alias test-fgcp -keyalg RSA -keysize 1024 -validity 5475 -dname "CN=localhost" -keystore
|
||||
// jclouds-test-fgcp.p12 -storepass jcloudsjclouds -storetype pkcs12
|
||||
String cert = "/certs/jclouds-test-fgcp.p12";
|
||||
String keyPassword = "jcloudsjclouds";
|
||||
|
||||
URL url = this.getClass().getResource(cert);
|
||||
String certPath = url.getFile();
|
||||
|
||||
KeyStore ks = module.provideKeyStore(crypto, certPath, keyPassword);
|
||||
KeyStore ks = new KeyStoreSupplier(crypto, Suppliers.ofInstance(new Credentials(certPath, "jcloudsjclouds")))
|
||||
.get();
|
||||
|
||||
assertNotNull(ks.getCertificate("test-fgcp"), "cert with alias");
|
||||
}
|
||||
|
||||
/* public void testKeyStoreAsPEM() throws IOException, InvalidKeySpecException, NoSuchAlgorithmException, KeyStoreException, CertificateException {
|
||||
assertNotNull(crypto);
|
||||
assertNotNull(module);
|
||||
|
||||
//openssl pkcs12 -nodes -in jclouds-test-fgcp.p12 -out jclouds-test-fgcp.pem
|
||||
// String privKeyFilename = "D:\\UserCert.pem.pkcs12-nodes";//_nobags";
|
||||
String cert = "/certs/jclouds-test-fgcp.pem";
|
||||
String keyPassword = "jcloudsjclouds";
|
||||
|
||||
URL url = this.getClass().getResource(cert);
|
||||
String certPath = url.getFile();
|
||||
Scanner scanner = new Scanner(new File(certPath));
|
||||
String content = scanner.useDelimiter("\\A").next();
|
||||
|
||||
KeyStore ks = module.provideKeyStore(crypto, content, keyPassword);
|
||||
|
||||
assertNotNull(ks.getCertificate("test-fgcp"), "cert with alias");
|
||||
}
|
||||
*/
|
||||
/*
|
||||
* public void testKeyStoreAsPEM() throws IOException, InvalidKeySpecException, NoSuchAlgorithmException,
|
||||
* KeyStoreException, CertificateException { assertNotNull(crypto); assertNotNull(module);
|
||||
*
|
||||
* //openssl pkcs12 -nodes -in jclouds-test-fgcp.p12 -out jclouds-test-fgcp.pem // String privKeyFilename =
|
||||
* "D:\\UserCert.pem.pkcs12-nodes";//_nobags"; String cert = "/certs/jclouds-test-fgcp.pem"; String keyPassword =
|
||||
* "jcloudsjclouds";
|
||||
*
|
||||
* URL url = this.getClass().getResource(cert); String certPath = url.getFile(); Scanner scanner = new Scanner(new
|
||||
* File(certPath)); String content = scanner.useDelimiter("\\A").next();
|
||||
*
|
||||
* KeyStore ks = module.provideKeyStore(crypto, content, keyPassword);
|
||||
*
|
||||
* assertNotNull(ks.getCertificate("test-fgcp"), "cert with alias"); }
|
||||
*/
|
||||
}
|
||||
|
|
|
@ -18,12 +18,15 @@
|
|||
*/
|
||||
package org.jclouds.googlecompute.config;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.inject.Provides;
|
||||
import com.google.inject.TypeLiteral;
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
import static com.google.common.base.Suppliers.compose;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.googlecompute.GoogleComputeApi;
|
||||
import org.jclouds.googlecompute.GoogleComputeAsyncApi;
|
||||
import org.jclouds.googlecompute.domain.Operation;
|
||||
|
@ -52,13 +55,16 @@ import org.jclouds.http.annotation.ServerError;
|
|||
import org.jclouds.json.config.GsonModule.DateAdapter;
|
||||
import org.jclouds.json.config.GsonModule.Iso8601DateAdapter;
|
||||
import org.jclouds.rest.ConfiguresRestClient;
|
||||
import org.jclouds.rest.annotations.Identity;
|
||||
import org.jclouds.rest.config.RestClientModule;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.inject.Provides;
|
||||
import com.google.inject.TypeLiteral;
|
||||
|
||||
/**
|
||||
* Configures the GoogleCompute connection.
|
||||
|
@ -97,10 +103,15 @@ public class GoogleComputeRestClientModule extends RestClientModule<GoogleComput
|
|||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
@UserProject
|
||||
public String provideProject(@Identity String identity) {
|
||||
checkState(identity.indexOf("@") != 1, "identity should be in project_id@developer.gserviceaccount.com format");
|
||||
return Iterables.get(Splitter.on("@").split(identity), 0);
|
||||
public Supplier<String> supplyProject(
|
||||
@org.jclouds.location.Provider final Supplier<Credentials> creds) {
|
||||
return compose(new Function<Credentials, String>() {
|
||||
public String apply(Credentials in) {
|
||||
checkState(in.identity.indexOf("@") != 1, "identity should be in project_id@developer.gserviceaccount.com format");
|
||||
return Iterables.get(Splitter.on("@").split(in.identity), 0);
|
||||
}
|
||||
}, creds);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -19,16 +19,17 @@
|
|||
|
||||
package org.jclouds.googlecompute.predicates;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.inject.Inject;
|
||||
import org.jclouds.googlecompute.GoogleComputeApi;
|
||||
import org.jclouds.googlecompute.config.UserProject;
|
||||
import org.jclouds.googlecompute.domain.Operation;
|
||||
import org.jclouds.googlecompute.features.OperationApi;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import org.jclouds.googlecompute.GoogleComputeApi;
|
||||
import org.jclouds.googlecompute.config.UserProject;
|
||||
import org.jclouds.googlecompute.domain.Operation;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.inject.Inject;
|
||||
|
||||
/**
|
||||
* Tests that an Operation is done, returning the completed Operation when it is.
|
||||
|
@ -37,17 +38,19 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||
*/
|
||||
public class OperationDonePredicate implements Predicate<AtomicReference<Operation>> {
|
||||
|
||||
private OperationApi api;
|
||||
private final GoogleComputeApi api;
|
||||
private final Supplier<String> project;
|
||||
|
||||
@Inject
|
||||
OperationDonePredicate(GoogleComputeApi api, @UserProject String project) {
|
||||
this.api = api.getOperationApiForProject(project);
|
||||
OperationDonePredicate(GoogleComputeApi api, @UserProject Supplier<String> project) {
|
||||
this.api = api;
|
||||
this.project = project;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(AtomicReference<Operation> input) {
|
||||
checkNotNull(input, "input");
|
||||
Operation current = api.get(input.get().getName());
|
||||
Operation current = api.getOperationApiForProject(project.get()).get(input.get().getName());
|
||||
switch (current.getStatus()) {
|
||||
case DONE:
|
||||
input.set(current);
|
||||
|
|
|
@ -37,6 +37,7 @@ import org.jclouds.oauth.v2.OAuthTestUtils;
|
|||
import org.jclouds.rest.RestContext;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.reflect.TypeToken;
|
||||
import com.google.inject.Key;
|
||||
import com.google.inject.TypeLiteral;
|
||||
|
@ -78,7 +79,8 @@ public class BaseGoogleComputeApiLiveTest extends BaseContextLiveTest<RestContex
|
|||
}
|
||||
|
||||
protected String getUserProject() {
|
||||
return context.utils().injector().getInstance(Key.get(String.class, UserProject.class));
|
||||
return context.utils().injector().getInstance(Key.get(new TypeLiteral<Supplier<String>>() {
|
||||
}, UserProject.class)).get();
|
||||
}
|
||||
|
||||
protected Predicate<AtomicReference<Operation>> getOperationDonePredicate() {
|
||||
|
|
|
@ -19,18 +19,19 @@
|
|||
package org.jclouds.jenkins.v1.filters;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.jclouds.jenkins.v1.JenkinsApiMetadata.ANONYMOUS_IDENTITY;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.http.HttpException;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpRequestFilter;
|
||||
import org.jclouds.http.filters.BasicAuthentication;
|
||||
import org.jclouds.jenkins.v1.JenkinsApiMetadata;
|
||||
import org.jclouds.rest.annotations.Identity;
|
||||
import org.jclouds.location.Provider;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
import com.google.common.base.Supplier;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
|
@ -39,18 +40,19 @@ import com.google.common.base.Optional;
|
|||
@Singleton
|
||||
public class BasicAuthenticationUnlessAnonymous implements HttpRequestFilter {
|
||||
|
||||
private final Optional<BasicAuthentication> auth;
|
||||
private final Supplier<Credentials> creds;
|
||||
private final BasicAuthentication auth;
|
||||
|
||||
@Inject
|
||||
public BasicAuthenticationUnlessAnonymous(@Identity String user, BasicAuthentication auth) {
|
||||
this.auth = JenkinsApiMetadata.ANONYMOUS_IDENTITY.equals(checkNotNull(user, "user")) ? Optional
|
||||
.<BasicAuthentication> absent() : Optional.of(checkNotNull(auth, "auth"));
|
||||
public BasicAuthenticationUnlessAnonymous(@Provider Supplier<Credentials> creds, BasicAuthentication auth) {
|
||||
this.creds = checkNotNull(creds, "creds");
|
||||
this.auth = checkNotNull(auth, "auth");
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpRequest filter(HttpRequest request) throws HttpException {
|
||||
if (auth.isPresent())
|
||||
return auth.get().filter(request);
|
||||
return request;
|
||||
if (ANONYMOUS_IDENTITY.equals(checkNotNull(creds.get().identity, "user")))
|
||||
return request;
|
||||
return auth.filter(request);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
*/
|
||||
package org.jclouds.nodepool.config;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
import static org.jclouds.nodepool.config.NodePoolProperties.BACKEND_GROUP;
|
||||
|
||||
|
@ -82,15 +83,16 @@ public class BindBackendComputeService extends BindJcloudsModules {
|
|||
@Backend
|
||||
@Exposed
|
||||
protected Supplier<ComputeService> makeBackendComputeService(@Backend final String provider,
|
||||
@Backend final Set<Module> modules, @Provider final Credentials creds,
|
||||
@Backend final Set<Module> modules, @Provider final Supplier<Credentials> creds,
|
||||
@Backend final Supplier<Properties> overrides, final Closer closer) {
|
||||
return Suppliers.memoize(new Supplier<ComputeService>() {
|
||||
|
||||
@Override
|
||||
public ComputeService get() {
|
||||
Credentials currentCreds = checkNotNull(creds.get(), "credential supplier returned null");
|
||||
ComputeServiceContext ctx = ContextBuilder.newBuilder(provider)
|
||||
.credentials(creds.identity, creds.credential).overrides(overrides.get()).modules(modules)
|
||||
.buildView(ComputeServiceContext.class);
|
||||
.credentials(currentCreds.identity, currentCreds.credential).overrides(overrides.get())
|
||||
.modules(modules).buildView(ComputeServiceContext.class);
|
||||
closer.addToClose(ctx);
|
||||
return ctx.getComputeService();
|
||||
}
|
||||
|
|
|
@ -27,9 +27,7 @@ import java.util.Properties;
|
|||
import org.jclouds.ContextBuilder;
|
||||
import org.jclouds.compute.ComputeService;
|
||||
import org.jclouds.logging.slf4j.config.SLF4JLoggingModule;
|
||||
import org.jclouds.nodepool.Backend;
|
||||
import org.jclouds.nodepool.config.NodePoolProperties;
|
||||
import org.jclouds.rest.annotations.Credential;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
|
@ -58,8 +56,6 @@ public class NodePoolComputeServiceContextTest {
|
|||
.getInstance(Key.get(new TypeLiteral<Supplier<ComputeService>>() {
|
||||
}, Backend.class)).get();
|
||||
|
||||
assertEquals(stub.getContext().unwrap().getIdentity(), "foo");
|
||||
assertEquals(stub.getContext().utils().injector().getInstance(Key.get(String.class, Credential.class)), "bar");
|
||||
assertEquals(stub.getContext().unwrap().getProviderMetadata().getEndpoint(), "gooend");
|
||||
assertEquals(stub.getContext().unwrap().getProviderMetadata().getApiMetadata().getVersion(), "1.1");
|
||||
assertEquals(stub.getContext().unwrap().getProviderMetadata().getApiMetadata().getBuildVersion().get(), "1.1-2");
|
||||
|
|
|
@ -31,7 +31,6 @@ import org.jclouds.domain.Credentials;
|
|||
import org.jclouds.domain.LoginCredentials;
|
||||
import org.jclouds.logging.slf4j.config.SLF4JLoggingModule;
|
||||
import org.jclouds.nodepool.Backend;
|
||||
import org.jclouds.rest.annotations.Credential;
|
||||
import org.jclouds.ssh.SshClient;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
|
@ -65,8 +64,6 @@ public class BindBackendComputeServiceTest {
|
|||
.getInstance(Key.get(new TypeLiteral<Supplier<ComputeService>>() {
|
||||
}, Backend.class)).get();
|
||||
|
||||
assertEquals(stub.getContext().unwrap().getIdentity(), "foo");
|
||||
assertEquals(stub.getContext().utils().injector().getInstance(Key.get(String.class, Credential.class)), "bar");
|
||||
assertEquals(stub.getContext().unwrap().getProviderMetadata().getEndpoint(), "gooend");
|
||||
assertEquals(stub.getContext().unwrap().getProviderMetadata().getApiMetadata().getVersion(), "1.1");
|
||||
assertEquals(stub.getContext().unwrap().getProviderMetadata().getApiMetadata().getBuildVersion().get(), "1.1-2");
|
||||
|
|
|
@ -69,7 +69,6 @@ public class OAuthCredentials extends Credentials {
|
|||
return this;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public OAuthCredentials build() {
|
||||
return new OAuthCredentials(checkNotNull(identity), credential, privateKey);
|
||||
}
|
||||
|
|
|
@ -18,74 +18,98 @@
|
|||
*/
|
||||
package org.jclouds.oauth.v2.functions;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
import org.jclouds.crypto.Pems;
|
||||
import org.jclouds.io.Payloads;
|
||||
import org.jclouds.oauth.v2.domain.OAuthCredentials;
|
||||
import org.jclouds.rest.annotations.Credential;
|
||||
import org.jclouds.rest.annotations.Identity;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
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.crypto.Pems.privateKeySpec;
|
||||
import static org.jclouds.io.Payloads.newStringPayload;
|
||||
import static org.jclouds.oauth.v2.OAuthConstants.NO_ALGORITHM;
|
||||
import static org.jclouds.oauth.v2.OAuthConstants.OAUTH_ALGORITHM_NAMES_TO_KEYFACTORY_ALGORITHM_NAMES;
|
||||
import static org.jclouds.oauth.v2.config.OAuthProperties.SIGNATURE_OR_MAC_ALGORITHM;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
import java.io.IOException;
|
||||
import java.security.KeyFactory;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
|
||||
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_KEYFACTORY_ALGORITHM_NAMES;
|
||||
import static org.jclouds.oauth.v2.config.OAuthProperties.SIGNATURE_OR_MAC_ALGORITHM;
|
||||
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 com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* @author David Alves
|
||||
* @see org.jclouds.oauth.v2.OAuthConstants#OAUTH_ALGORITHM_NAMES_TO_KEYFACTORY_ALGORITHM_NAMES
|
||||
*/
|
||||
@Singleton
|
||||
public class OAuthCredentialsSupplier implements Supplier<OAuthCredentials> {
|
||||
|
||||
|
||||
private final String identity;
|
||||
private final String privateKeyInPemFormat;
|
||||
private final String keyFactoryAlgorithm;
|
||||
private OAuthCredentials credentials;
|
||||
private final Supplier<Credentials> creds;
|
||||
private final LoadingCache<Credentials, OAuthCredentials> keyCache;
|
||||
|
||||
@Inject
|
||||
public OAuthCredentialsSupplier(@Identity String identity,
|
||||
@Credential String privateKeyInPemFormat,
|
||||
@Named(SIGNATURE_OR_MAC_ALGORITHM) String signatureOrMacAlgorithm) {
|
||||
this.identity = identity;
|
||||
this.privateKeyInPemFormat = privateKeyInPemFormat;
|
||||
public OAuthCredentialsSupplier(@Provider Supplier<Credentials> creds, OAuthCredentialsForCredentials loader,
|
||||
@Named(SIGNATURE_OR_MAC_ALGORITHM) String signatureOrMacAlgorithm) {
|
||||
this.creds = creds;
|
||||
checkState(OAUTH_ALGORITHM_NAMES_TO_KEYFACTORY_ALGORITHM_NAMES.containsKey(signatureOrMacAlgorithm),
|
||||
format("No mapping for key factory for algorithm: %s", signatureOrMacAlgorithm));
|
||||
this.keyFactoryAlgorithm = OAUTH_ALGORITHM_NAMES_TO_KEYFACTORY_ALGORITHM_NAMES.get(signatureOrMacAlgorithm);
|
||||
format("No mapping for key factory for algorithm: %s", signatureOrMacAlgorithm));
|
||||
// throw out the private key related to old credentials
|
||||
this.keyCache = CacheBuilder.newBuilder().maximumSize(2).build(checkNotNull(loader, "loader"));
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void loadPrivateKey() throws NoSuchAlgorithmException, IOException, InvalidKeySpecException {
|
||||
if (keyFactoryAlgorithm.equals(NO_ALGORITHM)) {
|
||||
this.credentials = new OAuthCredentials.Builder().identity(identity).credential
|
||||
(privateKeyInPemFormat).build();
|
||||
return;
|
||||
/**
|
||||
* it is relatively expensive to extract a private key from a PEM. cache the relationship between current credentials
|
||||
* so that the private key is only recalculated once.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
static class OAuthCredentialsForCredentials extends CacheLoader<Credentials, OAuthCredentials> {
|
||||
private final String keyFactoryAlgorithm;
|
||||
|
||||
@Inject
|
||||
public 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) {
|
||||
try {
|
||||
String identity = in.identity;
|
||||
String privateKeyInPemFormat = in.credential;
|
||||
if (keyFactoryAlgorithm.equals(NO_ALGORITHM)) {
|
||||
return new OAuthCredentials.Builder().identity(identity).credential(privateKeyInPemFormat).build();
|
||||
}
|
||||
KeyFactory keyFactory = KeyFactory.getInstance(keyFactoryAlgorithm);
|
||||
PrivateKey privateKey = keyFactory.generatePrivate(privateKeySpec(newStringPayload(privateKeyInPemFormat)));
|
||||
return new OAuthCredentials.Builder().identity(identity).credential(privateKeyInPemFormat)
|
||||
.privateKey(privateKey).build();
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw propagate(e);
|
||||
} catch (InvalidKeySpecException e) {
|
||||
throw propagate(e);
|
||||
} catch (IOException e) {
|
||||
throw propagate(e);
|
||||
}
|
||||
}
|
||||
KeyFactory keyFactory = KeyFactory.getInstance(keyFactoryAlgorithm);
|
||||
PrivateKey privateKey = keyFactory.generatePrivate(Pems.privateKeySpec(Payloads.newStringPayload
|
||||
(privateKeyInPemFormat)));
|
||||
this.credentials = new OAuthCredentials.Builder().identity(identity).credential
|
||||
(privateKeyInPemFormat).privateKey(privateKey).build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public OAuthCredentials get() {
|
||||
return this.credentials;
|
||||
return keyCache.getUnchecked(checkNotNull(creds.get(), "credential supplier returned null"));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -18,9 +18,10 @@
|
|||
*/
|
||||
package org.jclouds.oauth.v2.functions;
|
||||
|
||||
import org.jclouds.oauth.v2.domain.OAuthCredentials;
|
||||
import org.jclouds.util.Strings2;
|
||||
import org.testng.annotations.Test;
|
||||
import static com.google.common.base.Suppliers.ofInstance;
|
||||
import static org.jclouds.util.Strings2.toStringAndClose;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
|
@ -30,8 +31,10 @@ import java.security.UnrecoverableKeyException;
|
|||
import java.security.cert.CertificateException;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.oauth.v2.domain.OAuthCredentials;
|
||||
import org.jclouds.oauth.v2.functions.OAuthCredentialsSupplier.OAuthCredentialsForCredentials;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
* Test loading the credentials by extracting a pk from a PKCS12 keystore.
|
||||
|
@ -40,10 +43,9 @@ import static org.testng.Assert.assertNotNull;
|
|||
public class OAuthCredentialsFromPKTest {
|
||||
|
||||
public static OAuthCredentials loadOAuthCredentials() throws IOException, NoSuchAlgorithmException,
|
||||
CertificateException, InvalidKeySpecException {
|
||||
OAuthCredentialsSupplier loader = new OAuthCredentialsSupplier("foo",
|
||||
Strings2.toStringAndClose(new FileInputStream("src/test/resources/testpk.pem")), "RS256");
|
||||
loader.loadPrivateKey();
|
||||
CertificateException, InvalidKeySpecException {
|
||||
OAuthCredentialsSupplier loader = new OAuthCredentialsSupplier(ofInstance(new Credentials("foo",
|
||||
toStringAndClose(new FileInputStream("src/test/resources/testpk.pem")))), new OAuthCredentialsForCredentials("RS256"), "RS256");
|
||||
return loader.get();
|
||||
}
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@ import javax.inject.Named;
|
|||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.compute.domain.CIMOperatingSystem;
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.http.HttpErrorHandler;
|
||||
import org.jclouds.http.annotation.ClientError;
|
||||
import org.jclouds.http.annotation.Redirection;
|
||||
|
@ -42,7 +43,6 @@ import org.jclouds.json.Json;
|
|||
import org.jclouds.location.Provider;
|
||||
import org.jclouds.location.suppliers.ImplicitLocationSupplier;
|
||||
import org.jclouds.rest.ConfiguresRestClient;
|
||||
import org.jclouds.rest.annotations.Identity;
|
||||
import org.jclouds.rest.config.RestClientModule;
|
||||
import org.jclouds.rest.suppliers.MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier;
|
||||
import org.jclouds.savvis.vpdc.VPDCApi;
|
||||
|
@ -107,12 +107,12 @@ public class VPDCRestClientModule extends RestClientModule<VPDCApi, VPDCAsyncApi
|
|||
@org.jclouds.savvis.vpdc.internal.Org
|
||||
@Singleton
|
||||
protected Supplier<Set<org.jclouds.savvis.vpdc.domain.Resource>> provideOrgs(Supplier<VCloudSession> cache,
|
||||
@Identity final String user) {
|
||||
@org.jclouds.location.Provider final Supplier<Credentials> creds) {
|
||||
return Suppliers.compose(new Function<VCloudSession, Set<org.jclouds.savvis.vpdc.domain.Resource>>() {
|
||||
|
||||
@Override
|
||||
public Set<org.jclouds.savvis.vpdc.domain.Resource> apply(VCloudSession input) {
|
||||
checkState(input.getOrgs().size() > 0, "No orgs present for user: " + user);
|
||||
checkState(input.getOrgs().size() > 0, "No orgs present for user: " + creds.get());
|
||||
return input.getOrgs();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package org.jclouds.smartos;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
|
@ -11,12 +13,10 @@ import java.util.regex.Pattern;
|
|||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.domain.LoginCredentials;
|
||||
import org.jclouds.javax.annotation.Nullable;
|
||||
import org.jclouds.json.Json;
|
||||
import org.jclouds.location.Provider;
|
||||
import org.jclouds.rest.annotations.Credential;
|
||||
import org.jclouds.rest.annotations.Identity;
|
||||
import org.jclouds.smartos.compute.domain.DataSet;
|
||||
import org.jclouds.smartos.compute.domain.VM;
|
||||
import org.jclouds.smartos.compute.domain.VmSpecification;
|
||||
|
@ -34,8 +34,7 @@ import com.google.common.util.concurrent.RateLimiter;
|
|||
*/
|
||||
public class SmartOSHostController {
|
||||
protected final String hostname;
|
||||
protected final String username;
|
||||
protected final String password;
|
||||
protected final Supplier<Credentials> creds;
|
||||
protected final SshClient.Factory sshClientFactory;
|
||||
protected final Json json;
|
||||
|
||||
|
@ -59,11 +58,10 @@ public class SmartOSHostController {
|
|||
}
|
||||
|
||||
@Inject
|
||||
protected SmartOSHostController(@Provider Supplier<URI> provider, @Nullable @Identity String identity,
|
||||
@Nullable @Credential String credential, SshClient.Factory sshFactory, Json json) {
|
||||
protected SmartOSHostController(@Provider Supplier<URI> provider,
|
||||
@org.jclouds.location.Provider final Supplier<Credentials> creds, SshClient.Factory sshFactory, Json json) {
|
||||
this.hostname = provider.get().getHost();
|
||||
this.username = identity;
|
||||
this.password = credential;
|
||||
this.creds = creds;
|
||||
this.sshClientFactory = sshFactory;
|
||||
this.json = json;
|
||||
}
|
||||
|
@ -76,22 +74,16 @@ public class SmartOSHostController {
|
|||
return hostname;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public SshClient.Factory getSshClientFactory() {
|
||||
return sshClientFactory;
|
||||
}
|
||||
|
||||
protected SshClient getConnection() {
|
||||
if (_connection == null) {
|
||||
Credentials currentCreds = checkNotNull(creds.get(), "credential supplier returned null");
|
||||
|
||||
LoginCredentials credentials = new LoginCredentials.Builder().user(username).password(password).build();
|
||||
LoginCredentials credentials = new LoginCredentials.Builder().user(currentCreds.identity)
|
||||
.password(currentCreds.credential).build();
|
||||
|
||||
_connection = getSshClientFactory().create(HostAndPort.fromParts(hostname, 22), credentials);
|
||||
|
||||
|
|
|
@ -18,13 +18,11 @@
|
|||
*/
|
||||
package org.jclouds.vcloud.director.v1_5.config;
|
||||
|
||||
import static com.google.common.base.Throwables.propagate;
|
||||
import static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL;
|
||||
import static org.jclouds.rest.config.BinderUtils.bindHttpApi;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.jclouds.domain.Credentials;
|
||||
|
@ -227,15 +225,11 @@ public class VCloudDirectorRestClientModule extends RestClientModule<VCloudDirec
|
|||
@Provides
|
||||
@Singleton
|
||||
protected Supplier<SessionWithToken> provideSessionWithTokenSupplier(
|
||||
final LoadingCache<Credentials, SessionWithToken> cache, @Provider final Credentials creds) {
|
||||
final LoadingCache<Credentials, SessionWithToken> cache, @Provider final Supplier<Credentials> creds) {
|
||||
return new Supplier<SessionWithToken>() {
|
||||
@Override
|
||||
public SessionWithToken get() {
|
||||
try {
|
||||
return cache.get(creds);
|
||||
} catch (ExecutionException e) {
|
||||
throw propagate(e.getCause());
|
||||
}
|
||||
return cache.getUnchecked(creds.get());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -22,18 +22,20 @@ import javax.inject.Inject;
|
|||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.annotations.Name;
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.lifecycle.Closer;
|
||||
import org.jclouds.location.Provider;
|
||||
import org.jclouds.providers.ProviderMetadata;
|
||||
import org.jclouds.rest.RestContext;
|
||||
import org.jclouds.rest.Utils;
|
||||
import org.jclouds.rest.annotations.Identity;
|
||||
import org.jclouds.rest.internal.RestContextImpl;
|
||||
import org.jclouds.vcloud.director.v1_5.VCloudDirectorContext;
|
||||
import org.jclouds.vcloud.director.v1_5.admin.VCloudDirectorAdminAsyncApi;
|
||||
import org.jclouds.vcloud.director.v1_5.admin.VCloudDirectorAdminApi;
|
||||
import org.jclouds.vcloud.director.v1_5.user.VCloudDirectorAsyncApi;
|
||||
import org.jclouds.vcloud.director.v1_5.admin.VCloudDirectorAdminAsyncApi;
|
||||
import org.jclouds.vcloud.director.v1_5.user.VCloudDirectorApi;
|
||||
import org.jclouds.vcloud.director.v1_5.user.VCloudDirectorAsyncApi;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.TypeLiteral;
|
||||
|
||||
|
@ -46,10 +48,11 @@ public class VCloudDirectorContextImpl extends RestContextImpl<VCloudDirectorApi
|
|||
private final RestContext<VCloudDirectorAdminApi, VCloudDirectorAdminAsyncApi> adminContext;
|
||||
|
||||
@Inject
|
||||
VCloudDirectorContextImpl(@Name String name, ProviderMetadata providerMetadata, @Identity String identity, Utils utils, Closer closer,
|
||||
Injector injector, RestContext<VCloudDirectorAdminApi, VCloudDirectorAdminAsyncApi> adminContext) {
|
||||
super(name, providerMetadata, identity, utils, closer, injector, TypeLiteral.get(VCloudDirectorApi.class),
|
||||
TypeLiteral.get(VCloudDirectorAsyncApi.class));
|
||||
VCloudDirectorContextImpl(@Name String name, ProviderMetadata providerMetadata,
|
||||
@Provider Supplier<Credentials> creds, Utils utils, Closer closer, Injector injector,
|
||||
RestContext<VCloudDirectorAdminApi, VCloudDirectorAdminAsyncApi> adminContext) {
|
||||
super(name, providerMetadata, creds, utils, closer, injector, TypeLiteral.get(VCloudDirectorApi.class),
|
||||
TypeLiteral.get(VCloudDirectorAsyncApi.class));
|
||||
this.adminContext = adminContext;
|
||||
}
|
||||
|
||||
|
|
|
@ -23,18 +23,11 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||
|
||||
import java.net.URI;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Named;
|
||||
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.domain.NodeMetadataBuilder;
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.domain.LoginCredentials;
|
||||
import org.jclouds.javax.annotation.Nullable;
|
||||
import org.jclouds.location.Provider;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.rest.annotations.Credential;
|
||||
import org.jclouds.rest.annotations.Identity;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Supplier;
|
||||
|
@ -43,33 +36,25 @@ import com.google.inject.Inject;
|
|||
import com.google.inject.Singleton;
|
||||
|
||||
@Singleton
|
||||
public class HardcodedHostToHostNodeMetadata implements
|
||||
Function<NodeMetadata, NodeMetadata> {
|
||||
|
||||
@Resource
|
||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||
protected Logger logger = Logger.NULL;
|
||||
|
||||
public class HardcodedHostToHostNodeMetadata implements Function<NodeMetadata, NodeMetadata> {
|
||||
|
||||
private final Supplier<URI> providerSupplier;
|
||||
private final String username;
|
||||
private final String password;
|
||||
private final Supplier<Credentials> creds;
|
||||
|
||||
@Inject
|
||||
public HardcodedHostToHostNodeMetadata(
|
||||
@Provider Supplier<URI> providerSupplier,
|
||||
@Nullable @Identity String identity,
|
||||
@Nullable @Credential String credential) {
|
||||
this.providerSupplier = checkNotNull(providerSupplier,
|
||||
"endpoint to virtualbox websrvd is needed");
|
||||
this.username = identity;
|
||||
this.password = credential.equals("CHANGE_ME") ? "" : credential;
|
||||
public HardcodedHostToHostNodeMetadata(@Provider Supplier<URI> providerSupplier,
|
||||
@Provider Supplier<Credentials> creds) {
|
||||
this.providerSupplier = checkNotNull(providerSupplier, "endpoint to virtualbox websrvd is needed");
|
||||
this.creds = creds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NodeMetadata apply(NodeMetadata host) {
|
||||
Credentials currentCreds = checkNotNull(creds.get(), "credential supplier returned null");
|
||||
String username = currentCreds.identity;
|
||||
String password = currentCreds.credential.equals("CHANGE_ME") ? "" : currentCreds.credential;
|
||||
|
||||
LoginCredentials.Builder credentialsBuilder = LoginCredentials.builder(
|
||||
host.getCredentials()).user(username);
|
||||
LoginCredentials.Builder credentialsBuilder = LoginCredentials.builder(host.getCredentials()).user(username);
|
||||
if (!password.isEmpty())
|
||||
credentialsBuilder.password(password);
|
||||
|
||||
|
|
|
@ -29,13 +29,14 @@ import javax.inject.Named;
|
|||
|
||||
import org.jclouds.Constants;
|
||||
import org.jclouds.date.TimeStamp;
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpRequestFilter;
|
||||
import org.jclouds.http.HttpUtils;
|
||||
import org.jclouds.location.Provider;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.rest.annotations.Credential;
|
||||
import org.jclouds.rest.annotations.Identity;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
||||
/**
|
||||
|
@ -43,8 +44,7 @@ import com.google.common.collect.ImmutableMap;
|
|||
*/
|
||||
public class SharedKeyLiteAuthentication implements HttpRequestFilter {
|
||||
|
||||
private final String apiKey;
|
||||
private final String secret;
|
||||
private final Supplier<Credentials> creds;
|
||||
private final Long timeStamp;
|
||||
private final HttpUtils utils;
|
||||
|
||||
|
@ -53,10 +53,8 @@ public class SharedKeyLiteAuthentication implements HttpRequestFilter {
|
|||
Logger signatureLog = Logger.NULL;
|
||||
|
||||
@Inject
|
||||
public SharedKeyLiteAuthentication(@Identity String apiKey, @Credential String secret, @TimeStamp Long timeStamp,
|
||||
HttpUtils utils) {
|
||||
this.apiKey = apiKey;
|
||||
this.secret = secret;
|
||||
public SharedKeyLiteAuthentication(@Provider Supplier<Credentials> creds, @TimeStamp Long timeStamp, HttpUtils utils) {
|
||||
this.creds = creds;
|
||||
this.timeStamp = timeStamp;
|
||||
this.utils = utils;
|
||||
}
|
||||
|
@ -65,13 +63,14 @@ public class SharedKeyLiteAuthentication implements HttpRequestFilter {
|
|||
public HttpRequest filter(HttpRequest request) {
|
||||
String toSign = createStringToSign();
|
||||
String signatureMd5 = getMd5For(toSign);
|
||||
request = request.toBuilder().replaceQueryParams(ImmutableMap.of("sig", signatureMd5, "api_key" ,apiKey)).build();
|
||||
request = request.toBuilder()
|
||||
.replaceQueryParams(ImmutableMap.of("sig", signatureMd5, "api_key", creds.get().identity)).build();
|
||||
utils.logRequest(signatureLog, request, "<<");
|
||||
return request;
|
||||
}
|
||||
|
||||
private String createStringToSign() {
|
||||
return format("%s%s%s", apiKey, secret, timeStamp);
|
||||
return format("%s%s%s", creds.get().identity, creds.get().credential, timeStamp);
|
||||
}
|
||||
|
||||
private String getMd5For(String stringToHash) {
|
||||
|
|
|
@ -33,7 +33,6 @@ import static org.jclouds.util.Strings2.toInputStream;
|
|||
import java.io.IOException;
|
||||
import java.security.InvalidKeyException;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
|
@ -42,6 +41,7 @@ import org.jclouds.blobstore.domain.Blob;
|
|||
import org.jclouds.blobstore.functions.BlobToHttpGetOptions;
|
||||
import org.jclouds.crypto.Crypto;
|
||||
import org.jclouds.date.TimeStamp;
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.hpcloud.objectstorage.HPCloudObjectStorageAsyncApi;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.options.GetOptions;
|
||||
|
@ -50,8 +50,6 @@ import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
|
|||
import org.jclouds.openstack.swift.blobstore.functions.BlobToObject;
|
||||
import org.jclouds.openstack.swift.domain.SwiftObject;
|
||||
import org.jclouds.reflect.Invocation;
|
||||
import org.jclouds.rest.annotations.Credential;
|
||||
import org.jclouds.rest.annotations.Identity;
|
||||
import org.jclouds.rest.internal.GeneratedHttpRequest;
|
||||
import org.jclouds.rest.internal.RestAnnotationProcessor;
|
||||
|
||||
|
@ -75,9 +73,7 @@ public class HPCloudObjectStorageBlobRequestSigner implements BlobRequestSigner
|
|||
|
||||
private final Provider<Long> unixEpochTimestampProvider;
|
||||
private final Supplier<Access> access;
|
||||
private String tenantId;
|
||||
private final String accessKeyId;
|
||||
private final String secretKey;
|
||||
private final Supplier<Credentials> creds;
|
||||
|
||||
private final BlobToObject blobToObject;
|
||||
private final BlobToHttpGetOptions blob2HttpGetOptions;
|
||||
|
@ -89,16 +85,15 @@ public class HPCloudObjectStorageBlobRequestSigner implements BlobRequestSigner
|
|||
@Inject
|
||||
public HPCloudObjectStorageBlobRequestSigner(RestAnnotationProcessor<HPCloudObjectStorageAsyncApi> processor,
|
||||
BlobToObject blobToObject, BlobToHttpGetOptions blob2HttpGetOptions, Crypto crypto,
|
||||
@TimeStamp Provider<Long> unixEpochTimestampProvider, Supplier<Access> access, @Identity String accessKey,
|
||||
@Credential String secretKey) throws SecurityException, NoSuchMethodException {
|
||||
@TimeStamp Provider<Long> unixEpochTimestampProvider, Supplier<Access> access,
|
||||
@org.jclouds.location.Provider final Supplier<Credentials> creds) throws SecurityException,
|
||||
NoSuchMethodException {
|
||||
this.processor = checkNotNull(processor, "processor");
|
||||
this.crypto = checkNotNull(crypto, "crypto");
|
||||
|
||||
this.unixEpochTimestampProvider = checkNotNull(unixEpochTimestampProvider, "unixEpochTimestampProvider");
|
||||
this.access = checkNotNull(access, "access");
|
||||
// accessKey is of the form tenantName:accessKeyId (not tenantId)
|
||||
this.accessKeyId = accessKey.substring(accessKey.indexOf(':') + 1);
|
||||
this.secretKey = secretKey;
|
||||
this.creds = checkNotNull(creds, "creds");
|
||||
|
||||
this.blobToObject = checkNotNull(blobToObject, "blobToObject");
|
||||
this.blob2HttpGetOptions = checkNotNull(blob2HttpGetOptions, "blob2HttpGetOptions");
|
||||
|
@ -111,12 +106,6 @@ public class HPCloudObjectStorageBlobRequestSigner implements BlobRequestSigner
|
|||
SwiftObject.class));
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void populateTenantId() {
|
||||
// Defer call from constructor since access.get issues an RPC.
|
||||
this.tenantId = access.get().getToken().getTenant().get().getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpRequest signGetBlob(String container, String name) {
|
||||
checkNotNull(container, "container");
|
||||
|
@ -166,6 +155,12 @@ public class HPCloudObjectStorageBlobRequestSigner implements BlobRequestSigner
|
|||
}
|
||||
|
||||
private HttpRequest signForTemporaryAccess(HttpRequest request, long timeInSeconds) {
|
||||
Credentials currentCreds = checkNotNull(creds.get(), "credential supplier returned null");
|
||||
// accessKey is of the form tenantName:accessKeyId (not tenantId)
|
||||
String accessKeyId = currentCreds.identity.substring(currentCreds.identity.indexOf(':') + 1);
|
||||
String secretKey = currentCreds.credential;
|
||||
String tenantId = access.get().getToken().getTenant().get().getId();
|
||||
|
||||
HttpRequest.Builder<?> builder = request.toBuilder();
|
||||
// HP Cloud does not use X-Auth-Token for temporary signed URLs and
|
||||
// leaking this allows clients arbitrary privileges until token timeout.
|
||||
|
|
Loading…
Reference in New Issue