mirror of https://github.com/apache/jclouds.git
Merge pull request #1181 from jclouds/dynamic-credentials
Dynamic credentials
This commit is contained in:
commit
4fbb70be7b
|
@ -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>>>() {
|
||||
|
@ -125,6 +124,12 @@ public class CloudStackComputeServiceAdapterLiveTest extends BaseCloudStackClien
|
|||
install(new FactoryModuleBuilder().build(StaticNATVirtualMachineInNetwork.Factory.class));
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
Supplier<Credentials> supplyCredentials(){
|
||||
return Suppliers.ofInstance(new Credentials(identity, credential));
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
protected Predicate<String> jobComplete(JobComplete jobComplete) {
|
||||
|
|
|
@ -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,6 +40,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;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -50,15 +50,8 @@ 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,
|
||||
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
|
||||
|
|
|
@ -29,13 +29,15 @@ import javax.inject.Singleton;
|
|||
|
||||
import org.jclouds.compute.domain.Hardware;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.domain.NodeMetadata.Status;
|
||||
import org.jclouds.compute.domain.Processor;
|
||||
import org.jclouds.compute.domain.Volume;
|
||||
import org.jclouds.compute.domain.NodeMetadata.Status;
|
||||
import org.jclouds.compute.domain.internal.VolumeImpl;
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.location.Provider;
|
||||
import org.jclouds.predicates.SocketOpen;
|
||||
import org.jclouds.rest.annotations.Identity;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
|
@ -68,9 +70,9 @@ public class StubComputeServiceDependenciesModule extends AbstractModule {
|
|||
|
||||
@Provides
|
||||
@Singleton
|
||||
protected ConcurrentMap<String, NodeMetadata> provideNodesForIdentity(@Identity String identity)
|
||||
protected ConcurrentMap<String, NodeMetadata> provideNodesForIdentity(@Provider Supplier<Credentials> creds)
|
||||
throws ExecutionException {
|
||||
return backing.get(identity);
|
||||
return backing.get(creds.get().identity);
|
||||
}
|
||||
|
||||
protected static final LoadingCache<String, AtomicInteger> nodeIds = CacheBuilder.newBuilder().build(
|
||||
|
@ -85,8 +87,8 @@ public class StubComputeServiceDependenciesModule extends AbstractModule {
|
|||
|
||||
@Provides
|
||||
@Named("NODE_ID")
|
||||
protected Integer provideNodeIdForIdentity(@Identity String identity) throws ExecutionException {
|
||||
return nodeIds.get(identity).incrementAndGet();
|
||||
protected Integer provideNodeIdForIdentity(@Provider Supplier<Credentials> creds) throws ExecutionException {
|
||||
return nodeIds.get(creds.get().identity).incrementAndGet();
|
||||
}
|
||||
|
||||
@Singleton
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
*/
|
||||
package org.jclouds;
|
||||
|
||||
import static com.google.common.base.Objects.toStringHelper;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Predicates.containsPattern;
|
||||
import static com.google.common.base.Predicates.instanceOf;
|
||||
|
@ -30,6 +31,8 @@ import static com.google.common.collect.Iterables.filter;
|
|||
import static com.google.common.collect.Iterables.find;
|
||||
import static com.google.common.collect.Iterables.transform;
|
||||
import static com.google.common.collect.Lists.newArrayList;
|
||||
import static com.google.common.collect.Lists.newArrayListWithCapacity;
|
||||
import static com.google.common.collect.Maps.filterKeys;
|
||||
import static com.google.common.util.concurrent.MoreExecutors.sameThreadExecutor;
|
||||
import static org.jclouds.Constants.PROPERTY_API;
|
||||
import static org.jclouds.Constants.PROPERTY_API_VERSION;
|
||||
|
@ -84,12 +87,12 @@ import com.google.common.base.Objects;
|
|||
import com.google.common.base.Optional;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.base.Suppliers;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMultimap;
|
||||
import com.google.common.collect.ImmutableMultimap.Builder;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.reflect.TypeToken;
|
||||
import com.google.common.util.concurrent.ExecutionList;
|
||||
import com.google.inject.Guice;
|
||||
|
@ -189,18 +192,18 @@ public class ContextBuilder {
|
|||
protected final String providerId;
|
||||
protected Optional<String> endpoint = Optional.absent();
|
||||
protected Optional<String> identity = Optional.absent();
|
||||
protected Optional<Supplier<Credentials>> credentialsSupplierOption = Optional.absent();
|
||||
@Nullable
|
||||
protected String credential;
|
||||
protected ApiMetadata apiMetadata;
|
||||
protected String apiVersion;
|
||||
protected String buildVersion;
|
||||
protected Optional<Properties> overrides = Optional.absent();
|
||||
protected List<Module> modules = Lists.newArrayListWithCapacity(3);
|
||||
protected List<Module> modules = newArrayListWithCapacity(3);
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return Objects.toStringHelper("").add("providerMetadata", providerMetadata).add("apiMetadata", apiMetadata)
|
||||
.toString();
|
||||
return toStringHelper("").add("providerMetadata", providerMetadata).add("apiMetadata", apiMetadata).toString();
|
||||
}
|
||||
|
||||
protected ContextBuilder(ProviderMetadata providerMetadata) {
|
||||
|
@ -232,6 +235,20 @@ public class ContextBuilder {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the current login credentials. jclouds will not cache this value. Use this when you need to change
|
||||
* credentials at runtime.
|
||||
*/
|
||||
public ContextBuilder credentialsSupplier(Supplier<Credentials> credentialsSupplier) {
|
||||
this.credentialsSupplierOption = Optional.of(checkNotNull(credentialsSupplier, "credentialsSupplier"));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* constant value of the cloud identity and credential.
|
||||
*
|
||||
* @param credential (optional depending on {@link ApiMetadata#getCredentialName()}
|
||||
*/
|
||||
public ContextBuilder credentials(String identity, @Nullable String credential) {
|
||||
this.identity = Optional.of(checkNotNull(identity, "identity"));
|
||||
this.credential = credential;
|
||||
|
@ -289,14 +306,29 @@ public class ContextBuilder {
|
|||
|
||||
Properties expanded = expandProperties(resolved);
|
||||
|
||||
Supplier<Credentials> credentialsSupplier = buildCredentialsSupplier(expanded);
|
||||
|
||||
ProviderMetadata providerMetadata = new UpdateProviderMetadataFromProperties(apiMetadata, this.providerMetadata)
|
||||
.apply(expanded);
|
||||
|
||||
// We use either the specified name (optional) or a hash of provider/api, endpoint, api version & identity. Hash
|
||||
// is used to be something readable.
|
||||
return buildInjector(name.or(String.valueOf(Objects.hashCode(providerMetadata.getId(),
|
||||
providerMetadata.getEndpoint(), providerMetadata.getApiMetadata().getVersion(), credentialsSupplier))),
|
||||
providerMetadata, credentialsSupplier, modules);
|
||||
}
|
||||
|
||||
protected Supplier<Credentials> buildCredentialsSupplier(Properties expanded) {
|
||||
Credentials creds = new Credentials(getAndRemove(expanded, PROPERTY_IDENTITY), getAndRemove(expanded,
|
||||
PROPERTY_CREDENTIAL));
|
||||
|
||||
ProviderMetadata providerMetadata = new UpdateProviderMetadataFromProperties(apiMetadata, this.providerMetadata).apply(expanded);
|
||||
|
||||
//We use either the specified name (optional) or a hash of provider/api, endpoint, api version & identity. Hash is used to be something readable.
|
||||
return buildInjector(name.or(String.valueOf(Objects.hashCode(providerMetadata.getId(),
|
||||
providerMetadata.getEndpoint(), providerMetadata.getApiMetadata().getVersion(), creds.identity))), providerMetadata, creds, modules);
|
||||
Supplier<Credentials> credentialsSupplier;
|
||||
if (credentialsSupplierOption.isPresent()) {
|
||||
credentialsSupplier = credentialsSupplierOption.get();
|
||||
} else {
|
||||
credentialsSupplier = Suppliers.ofInstance(creds);
|
||||
}
|
||||
return credentialsSupplier;
|
||||
}
|
||||
|
||||
private static String getAndRemove(Properties expanded, String key) {
|
||||
|
@ -340,7 +372,7 @@ public class ContextBuilder {
|
|||
return Guice.createInjector(new BindPropertiesToExpandedValues(resolved)).getInstance(Properties.class);
|
||||
}
|
||||
|
||||
public static Injector buildInjector(String name, ProviderMetadata providerMetadata, Credentials creds, List<Module> inputModules) {
|
||||
public static Injector buildInjector(String name, ProviderMetadata providerMetadata, Supplier<Credentials> creds, List<Module> inputModules) {
|
||||
List<Module> modules = newArrayList();
|
||||
modules.addAll(inputModules);
|
||||
boolean restModuleSpecifiedByUser = restClientModulePresent(inputModules);
|
||||
|
@ -411,8 +443,7 @@ public class ContextBuilder {
|
|||
@SuppressWarnings( { "unchecked" })
|
||||
static Map<String, Object> propertiesPrefixedWithJcloudsApiOrProviderId(Properties properties, String apiId,
|
||||
String providerId) {
|
||||
return Maps.filterKeys(Map.class.cast(properties), containsPattern("^(jclouds|" + providerId + "|" + apiId
|
||||
+ ").*"));
|
||||
return filterKeys(Map.class.cast(properties), containsPattern("^(jclouds|" + providerId + "|" + apiId + ").*"));
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
|
|
|
@ -26,12 +26,13 @@ import static java.lang.String.format;
|
|||
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.rest.annotations.Credential;
|
||||
import org.jclouds.rest.annotations.Identity;
|
||||
import org.jclouds.location.Provider;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
|
||||
/**
|
||||
* Uses Basic Authentication to sign the request.
|
||||
|
@ -43,22 +44,24 @@ import org.jclouds.rest.annotations.Identity;
|
|||
@Singleton
|
||||
public class BasicAuthentication implements HttpRequestFilter {
|
||||
|
||||
private final String header;
|
||||
private final Supplier<Credentials> creds;
|
||||
|
||||
@Inject
|
||||
public BasicAuthentication(@Identity String user, @Credential String password, Crypto crypto) {
|
||||
checkNotNull(user, "user");
|
||||
checkNotNull(password, "password");
|
||||
this.header = basic(user, password);
|
||||
public BasicAuthentication(@Provider Supplier<Credentials> creds) {
|
||||
this.creds = checkNotNull(creds, "creds");
|
||||
}
|
||||
|
||||
public static String basic(String user, String password) {
|
||||
return new StringBuilder("Basic ").append(base64().encode(format("%s:%s", user, password).getBytes(UTF_8)))
|
||||
return new StringBuilder("Basic ").append(
|
||||
base64().encode(
|
||||
format("%s:%s", checkNotNull(user, "user"), checkNotNull(password, "password")).getBytes(UTF_8)))
|
||||
.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpRequest filter(HttpRequest request) throws HttpException {
|
||||
return request.toBuilder().replaceHeader(AUTHORIZATION, header).build();
|
||||
Credentials currentCreds = checkNotNull(creds.get(), "credential supplier returned null");
|
||||
return request.toBuilder().replaceHeader(AUTHORIZATION, basic(currentCreds.identity, currentCreds.credential))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,26 +18,31 @@
|
|||
*/
|
||||
package org.jclouds.internal;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.io.Closeables;
|
||||
import com.google.inject.Singleton;
|
||||
import static com.google.common.base.Objects.equal;
|
||||
import static com.google.common.base.Objects.toStringHelper;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.io.Closeables.closeQuietly;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.jclouds.Context;
|
||||
import org.jclouds.annotations.Name;
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.domain.LocationScope;
|
||||
import org.jclouds.lifecycle.Closer;
|
||||
import org.jclouds.location.Provider;
|
||||
import org.jclouds.providers.ProviderMetadata;
|
||||
import org.jclouds.rest.Utils;
|
||||
import org.jclouds.rest.annotations.Identity;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.inject.Singleton;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
|
@ -46,15 +51,16 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||
public class ContextImpl implements Context {
|
||||
|
||||
private final ProviderMetadata providerMetadata;
|
||||
private final String identity;
|
||||
private final Supplier<Credentials> creds;
|
||||
private final Utils utils;
|
||||
private final Closer closer;
|
||||
private final String name;
|
||||
|
||||
@Inject
|
||||
protected ContextImpl(@Name String name, ProviderMetadata providerMetadata, @Identity String identity, Utils utils, Closer closer) {
|
||||
protected ContextImpl(@Name String name, ProviderMetadata providerMetadata, @Provider Supplier<Credentials> creds,
|
||||
Utils utils, Closer closer) {
|
||||
this.providerMetadata = checkNotNull(providerMetadata, "providerMetadata");
|
||||
this.identity = checkNotNull(identity, "identity");
|
||||
this.creds = checkNotNull(creds, "creds");
|
||||
this.utils = checkNotNull(utils, "utils");
|
||||
this.closer = checkNotNull(closer, "closer");
|
||||
this.name = checkNotNull(name, "name");
|
||||
|
@ -65,7 +71,7 @@ public class ContextImpl implements Context {
|
|||
*/
|
||||
@Override
|
||||
public void close() {
|
||||
Closeables.closeQuietly(closer);
|
||||
closeQuietly(closer);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -89,7 +95,7 @@ public class ContextImpl implements Context {
|
|||
*/
|
||||
@Override
|
||||
public String getIdentity() {
|
||||
return identity;
|
||||
return creds.get().identity;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -134,7 +140,7 @@ public class ContextImpl implements Context {
|
|||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(providerMetadata, identity);
|
||||
return Objects.hashCode(providerMetadata, creds);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -149,7 +155,7 @@ public class ContextImpl implements Context {
|
|||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
ContextImpl that = ContextImpl.class.cast(obj);
|
||||
return Objects.equal(this.providerMetadata, that.providerMetadata) && Objects.equal(this.identity, that.identity);
|
||||
return equal(this.providerMetadata, that.providerMetadata) && equal(this.creds, that.creds);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -157,7 +163,7 @@ public class ContextImpl implements Context {
|
|||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return Objects.toStringHelper("").add("providerMetadata", providerMetadata).add("identity", identity).toString();
|
||||
return toStringHelper("").add("providerMetadata", providerMetadata).add("identity", getIdentity()).toString();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -191,7 +197,7 @@ public class ContextImpl implements Context {
|
|||
public Map<String, Object> getMetadata() {
|
||||
return ImmutableMap.<String, Object> of("endpoint", URI.create(providerMetadata.getEndpoint()), "apiVersion",
|
||||
providerMetadata.getApiMetadata().getVersion(), "buildVersion", providerMetadata.getApiMetadata()
|
||||
.getBuildVersion().or(""), "identity", identity);
|
||||
.getBuildVersion().or(""), "identity", getIdentity());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -33,9 +33,8 @@ import org.jclouds.providers.ProviderMetadata;
|
|||
import org.jclouds.rest.annotations.Api;
|
||||
import org.jclouds.rest.annotations.ApiVersion;
|
||||
import org.jclouds.rest.annotations.BuildVersion;
|
||||
import org.jclouds.rest.annotations.Credential;
|
||||
import org.jclouds.rest.annotations.Identity;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.reflect.TypeToken;
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Injector;
|
||||
|
@ -56,9 +55,9 @@ import com.google.inject.name.Names;
|
|||
public class BindProviderMetadataContextAndCredentials extends AbstractModule {
|
||||
|
||||
private final ProviderMetadata providerMetadata;
|
||||
private final Credentials creds;
|
||||
private final Supplier<Credentials> creds;
|
||||
|
||||
public BindProviderMetadataContextAndCredentials(ProviderMetadata providerMetadata, Credentials creds) {
|
||||
public BindProviderMetadataContextAndCredentials(ProviderMetadata providerMetadata, Supplier<Credentials> creds) {
|
||||
this.providerMetadata = checkNotNull(providerMetadata, "providerMetadata");
|
||||
this.creds = checkNotNull(creds, "creds");
|
||||
}
|
||||
|
@ -70,11 +69,7 @@ public class BindProviderMetadataContextAndCredentials extends AbstractModule {
|
|||
toBind.putAll(providerMetadata.getApiMetadata().getDefaultProperties());
|
||||
toBind.putAll(providerMetadata.getDefaultProperties());
|
||||
Names.bindProperties(binder(), toBind);
|
||||
bind(Credentials.class).annotatedWith(Provider.class).toInstance(creds);
|
||||
bindConstant().annotatedWith(Identity.class).to(creds.identity);
|
||||
// nullable
|
||||
bind(String.class).annotatedWith(Credential.class).toProvider(
|
||||
com.google.inject.util.Providers.of(creds.credential));
|
||||
bind(new TypeLiteral<Supplier<Credentials>>(){}).annotatedWith(Provider.class).toInstance(creds);
|
||||
bindConstant().annotatedWith(Provider.class).to(providerMetadata.getId());
|
||||
bind(new TypeLiteral<Set<String>>() {
|
||||
}).annotatedWith(Iso3166.class).toInstance(providerMetadata.getIso3166Codes());
|
||||
|
|
|
@ -1,42 +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.rest.annotations;
|
||||
|
||||
import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
|
||||
import static java.lang.annotation.ElementType.FIELD;
|
||||
import static java.lang.annotation.ElementType.METHOD;
|
||||
import static java.lang.annotation.ElementType.PARAMETER;
|
||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import javax.inject.Qualifier;
|
||||
|
||||
/**
|
||||
* Designates that this Resource qualifies an object to a key on a provider.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Target( { ANNOTATION_TYPE, FIELD, METHOD, PARAMETER })
|
||||
@Retention(RUNTIME)
|
||||
@Qualifier
|
||||
public @interface Credential {
|
||||
|
||||
}
|
|
@ -1,42 +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.rest.annotations;
|
||||
|
||||
import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
|
||||
import static java.lang.annotation.ElementType.FIELD;
|
||||
import static java.lang.annotation.ElementType.METHOD;
|
||||
import static java.lang.annotation.ElementType.PARAMETER;
|
||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import javax.inject.Qualifier;
|
||||
|
||||
/**
|
||||
* Designates that this Resource qualifies an object to an identity on a provider.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Target( { ANNOTATION_TYPE, FIELD, METHOD, PARAMETER })
|
||||
@Retention(RUNTIME)
|
||||
@Qualifier
|
||||
public @interface Identity {
|
||||
|
||||
}
|
|
@ -23,13 +23,15 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||
import javax.inject.Inject;
|
||||
|
||||
import org.jclouds.annotations.Name;
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.internal.ContextImpl;
|
||||
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 com.google.common.base.Supplier;
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Key;
|
||||
import com.google.inject.Singleton;
|
||||
|
@ -45,9 +47,10 @@ public class RestContextImpl<S, A> extends ContextImpl implements RestContext<S,
|
|||
private final S syncApi;
|
||||
|
||||
@Inject
|
||||
protected RestContextImpl(@Name String name, ProviderMetadata providerMetadata, @Identity String identity, Utils utils, Closer closer,
|
||||
Injector injector, TypeLiteral<S> syncApi, TypeLiteral<A> asyncApi) {
|
||||
super(name, providerMetadata, identity, utils, closer);
|
||||
protected RestContextImpl(@Name String name, ProviderMetadata providerMetadata,
|
||||
@Provider Supplier<Credentials> creds, Utils utils, Closer closer, Injector injector, TypeLiteral<S> syncApi,
|
||||
TypeLiteral<A> asyncApi) {
|
||||
super(name, providerMetadata, creds, utils, closer);
|
||||
checkNotNull(injector, "injector");
|
||||
this.asyncApi = injector.getInstance(Key.get(checkNotNull(asyncApi, "asyncApi")));
|
||||
this.syncApi = injector.getInstance(Key.get(checkNotNull(syncApi, "syncApi")));
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
*/
|
||||
package org.jclouds;
|
||||
|
||||
import static com.google.common.base.Suppliers.ofInstance;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.net.URI;
|
||||
|
@ -27,6 +28,7 @@ import java.util.Properties;
|
|||
import java.util.Set;
|
||||
|
||||
import org.jclouds.concurrent.config.ExecutorServiceModule;
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.events.config.EventBusModule;
|
||||
import org.jclouds.http.IntegrationTestAsyncClient;
|
||||
import org.jclouds.http.IntegrationTestClient;
|
||||
|
@ -40,7 +42,6 @@ import org.jclouds.providers.AnonymousProviderMetadata;
|
|||
import org.jclouds.providers.ProviderMetadata;
|
||||
import org.jclouds.rest.ConfiguresRestClient;
|
||||
import org.jclouds.rest.annotations.ApiVersion;
|
||||
import org.jclouds.rest.annotations.Identity;
|
||||
import org.jclouds.rest.config.CredentialStoreModule;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
|
@ -115,8 +116,23 @@ public class ContextBuilderTest {
|
|||
overrides.setProperty(Constants.PROPERTY_IDENTITY, "foo");
|
||||
overrides.setProperty(Constants.PROPERTY_CREDENTIAL, "BAR");
|
||||
ContextBuilder withCredsInProps = testContextBuilder().overrides(overrides);
|
||||
String identity = withCredsInProps.buildInjector().getInstance(Key.get(String.class, Identity.class));
|
||||
assertEquals(identity, "foo");
|
||||
Credentials creds = withCredsInProps.buildInjector()
|
||||
.getInstance(Key.get(new TypeLiteral<Supplier<Credentials>>() {
|
||||
}, Provider.class)).get();
|
||||
assertEquals(creds, new Credentials("foo", "BAR"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProviderMetadataWithCredentialsSetSupplier() {
|
||||
Properties overrides = new Properties();
|
||||
overrides.setProperty(Constants.PROPERTY_IDENTITY, "foo");
|
||||
overrides.setProperty(Constants.PROPERTY_CREDENTIAL, "BAR");
|
||||
ContextBuilder withCredsSupplier = testContextBuilder().credentialsSupplier(
|
||||
ofInstance(new Credentials("foo", "BAR")));
|
||||
Credentials creds = withCredsSupplier.buildInjector()
|
||||
.getInstance(Key.get(new TypeLiteral<Supplier<Credentials>>() {
|
||||
}, Provider.class)).get();
|
||||
assertEquals(creds, new Credentials("foo", "BAR"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
*/
|
||||
package org.jclouds.config;
|
||||
|
||||
import static com.google.common.base.Suppliers.ofInstance;
|
||||
import static org.easymock.EasyMock.createMock;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
|
@ -74,7 +75,7 @@ public class BindRestContextWithWildcardExtendsExplicitAndRawTypeTest {
|
|||
private Injector injectorFor(ProviderMetadata md) {
|
||||
return Guice.createInjector(
|
||||
new BindNameToContext("test"),
|
||||
new BindProviderMetadataContextAndCredentials(md, new Credentials("user", "pass")),
|
||||
new BindProviderMetadataContextAndCredentials(md, ofInstance(new Credentials("user", "pass"))),
|
||||
new BindRestContextWithWildcardExtendsExplicitAndRawType(RestApiMetadata.class.cast(md
|
||||
.getApiMetadata())),
|
||||
|
||||
|
|
|
@ -18,31 +18,50 @@
|
|||
*/
|
||||
package org.jclouds.http.filters;
|
||||
|
||||
import static com.google.common.base.Suppliers.ofInstance;
|
||||
import static com.google.common.collect.Queues.newArrayDeque;
|
||||
import static com.google.common.net.HttpHeaders.AUTHORIZATION;
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.util.Deque;
|
||||
|
||||
import org.jclouds.encryption.internal.JCECrypto;
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "unit")
|
||||
public class BasicAuthenticationTest {
|
||||
private static final Credentials credential1 = new Credentials("Aladdin", "open sesame");
|
||||
private static final Credentials credential2 = new Credentials("Little", "Mermaid");
|
||||
|
||||
private static final String USER = "Aladdin";
|
||||
private static final String PASSWORD = "open sesame";
|
||||
public void testAuth() {
|
||||
HttpRequest request = HttpRequest.builder().method("GET").endpoint("http://localhost").build();
|
||||
request = new BasicAuthentication(ofInstance(credential1)).filter(request);
|
||||
assertEquals(request.getFirstHeaderOrNull(AUTHORIZATION), "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==");
|
||||
request = new BasicAuthentication(ofInstance(credential2)).filter(request);
|
||||
assertEquals(request.getFirstHeaderOrNull(AUTHORIZATION), "Basic TGl0dGxlOk1lcm1haWQ=");
|
||||
}
|
||||
|
||||
public void testAuth() throws NoSuchAlgorithmException, CertificateException {
|
||||
BasicAuthentication filter = new BasicAuthentication(USER, PASSWORD, new JCECrypto(null));
|
||||
public void testAuthWithRuntimePasswordChange() {
|
||||
Supplier<Credentials> credentialRotation = new Supplier<Credentials>() {
|
||||
Deque<Credentials> rotation = newArrayDeque(asList(credential1, credential2));
|
||||
|
||||
public Credentials get() {
|
||||
return rotation.poll();
|
||||
}
|
||||
};
|
||||
BasicAuthentication filter = new BasicAuthentication(credentialRotation);
|
||||
HttpRequest request = HttpRequest.builder().method("GET").endpoint("http://localhost").build();
|
||||
request = filter.filter(request);
|
||||
assertEquals(request.getFirstHeaderOrNull(AUTHORIZATION), "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==");
|
||||
request = filter.filter(request);
|
||||
assertEquals(request.getFirstHeaderOrNull(AUTHORIZATION), "Basic TGl0dGxlOk1lcm1haWQ=");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -23,11 +23,14 @@ import static org.testng.Assert.assertEquals;
|
|||
import static org.testng.Assert.assertNotEquals;
|
||||
import static org.testng.Assert.fail;
|
||||
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.lifecycle.Closer;
|
||||
import org.jclouds.providers.ProviderMetadata;
|
||||
import org.jclouds.rest.Utils;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.base.Suppliers;
|
||||
import com.google.common.reflect.TypeToken;
|
||||
|
||||
/**
|
||||
|
@ -36,10 +39,12 @@ import com.google.common.reflect.TypeToken;
|
|||
@Test(groups = "unit", testName = "BaseViewTest")
|
||||
public class BaseViewTest {
|
||||
|
||||
static Supplier<Credentials> creds = Suppliers.ofInstance(new Credentials("identity", null));
|
||||
|
||||
private static class Water extends ContextImpl {
|
||||
|
||||
protected Water() {
|
||||
super("water", createMock(ProviderMetadata.class), "identity", createMock(Utils.class), createMock(Closer.class));
|
||||
super("water", createMock(ProviderMetadata.class), creds, createMock(Utils.class), createMock(Closer.class));
|
||||
}
|
||||
|
||||
public void close() {
|
||||
|
@ -49,7 +54,7 @@ public class BaseViewTest {
|
|||
private static class PeanutButter extends ContextImpl {
|
||||
|
||||
protected PeanutButter() {
|
||||
super("peanutbutter", createMock(ProviderMetadata.class), "identity", createMock(Utils.class), createMock(Closer.class));
|
||||
super("peanutbutter", createMock(ProviderMetadata.class), creds, createMock(Utils.class), createMock(Closer.class));
|
||||
}
|
||||
|
||||
public void close() {
|
||||
|
|
|
@ -41,11 +41,11 @@ import org.jclouds.providers.ProviderMetadata;
|
|||
import org.jclouds.rest.annotations.Api;
|
||||
import org.jclouds.rest.annotations.ApiVersion;
|
||||
import org.jclouds.rest.annotations.BuildVersion;
|
||||
import org.jclouds.rest.annotations.Credential;
|
||||
import org.jclouds.rest.annotations.Identity;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.base.Suppliers;
|
||||
import com.google.common.reflect.TypeToken;
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Key;
|
||||
|
@ -63,8 +63,6 @@ public class BindProviderMetadataContextAndCredentialsTest {
|
|||
private final javax.inject.Provider<Context> backend;
|
||||
private final ProviderMetadata providerMetadata;
|
||||
private final Credentials creds;
|
||||
private final String identity;
|
||||
private final String credential;
|
||||
private final String providerId;
|
||||
private final Set<String> iso3166Codes;
|
||||
private final String apiId;
|
||||
|
@ -73,9 +71,8 @@ public class BindProviderMetadataContextAndCredentialsTest {
|
|||
|
||||
@Inject
|
||||
private ExpectedBindings(@Provider javax.inject.Provider<Context> backend, ProviderMetadata providerMetadata,
|
||||
@Provider Credentials creds, @Identity String identity, @Nullable @Credential String credential,
|
||||
@Provider String providerId, @Iso3166 Set<String> iso3166Codes, @Api String apiId,
|
||||
@ApiVersion String apiVersion, @Nullable @BuildVersion String buildVersion,
|
||||
@Provider Supplier<Credentials> creds, @Provider String providerId, @Iso3166 Set<String> iso3166Codes,
|
||||
@Api String apiId, @ApiVersion String apiVersion, @Nullable @BuildVersion String buildVersion,
|
||||
@Provider TypeToken<? extends Context> backendToken, FilterStringsBoundToInjectorByName filter) {
|
||||
this.backend = backend;
|
||||
assertEquals(backendToken, providerMetadata.getApiMetadata().getContext());
|
||||
|
@ -86,11 +83,7 @@ public class BindProviderMetadataContextAndCredentialsTest {
|
|||
expected.putAll(providerMetadata.getApiMetadata().getDefaultProperties());
|
||||
expected.putAll(providerMetadata.getDefaultProperties());
|
||||
assertEquals(props, expected);
|
||||
this.creds = creds;
|
||||
this.identity = identity;
|
||||
assertEquals(identity, creds.identity);
|
||||
this.credential = credential;
|
||||
assertEquals(credential, creds.credential);
|
||||
this.creds = creds.get();
|
||||
this.providerId = providerId;
|
||||
assertEquals(providerId, providerMetadata.getId());
|
||||
this.iso3166Codes = iso3166Codes;
|
||||
|
@ -110,12 +103,13 @@ public class BindProviderMetadataContextAndCredentialsTest {
|
|||
|
||||
ProviderMetadata md = AnonymousProviderMetadata.forClientMappedToAsyncClientOnEndpoint(
|
||||
IntegrationTestClient.class, IntegrationTestAsyncClient.class, "http://localhost");
|
||||
Credentials creds = LoginCredentials.builder().user("user").password("password").build();
|
||||
Supplier<Credentials> creds = Suppliers.<Credentials> ofInstance(LoginCredentials.builder().user("user")
|
||||
.password("password").build());
|
||||
|
||||
ExpectedBindings bindings = Guice.createInjector(new BindProviderMetadataContextAndCredentials(md, creds))
|
||||
.getInstance(ExpectedBindings.class);
|
||||
assertEquals(bindings.identity, "user");
|
||||
assertEquals(bindings.credential, "password");
|
||||
assertEquals(bindings.creds.identity, "user");
|
||||
assertEquals(bindings.creds.credential, "password");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -123,12 +117,12 @@ public class BindProviderMetadataContextAndCredentialsTest {
|
|||
|
||||
ProviderMetadata md = AnonymousProviderMetadata.forClientMappedToAsyncClientOnEndpoint(
|
||||
IntegrationTestClient.class, IntegrationTestAsyncClient.class, "http://localhost");
|
||||
Credentials creds = LoginCredentials.builder().user("user").build();
|
||||
Supplier<Credentials> creds = Suppliers.<Credentials> ofInstance(LoginCredentials.builder().user("user").build());
|
||||
|
||||
ExpectedBindings bindings = Guice.createInjector(new BindProviderMetadataContextAndCredentials(md, creds))
|
||||
.getInstance(ExpectedBindings.class);
|
||||
assertEquals(bindings.identity, "user");
|
||||
assertEquals(bindings.credential, null);
|
||||
assertEquals(bindings.creds.identity, "user");
|
||||
assertEquals(bindings.creds.credential, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -138,7 +132,7 @@ public class BindProviderMetadataContextAndCredentialsTest {
|
|||
IntegrationTestClient.class, IntegrationTestAsyncClient.class, "http://localhost");
|
||||
ApiMetadata apiMd = md.getApiMetadata().toBuilder().buildVersion(null).build();
|
||||
md = md.toBuilder().apiMetadata(apiMd).build();
|
||||
Credentials creds = LoginCredentials.builder().user("user").build();
|
||||
Supplier<Credentials> creds = Suppliers.<Credentials> ofInstance(LoginCredentials.builder().user("user").build());
|
||||
|
||||
ExpectedBindings bindings = Guice.createInjector(new BindProviderMetadataContextAndCredentials(md, creds))
|
||||
.getInstance(ExpectedBindings.class);
|
||||
|
@ -154,7 +148,7 @@ public class BindProviderMetadataContextAndCredentialsTest {
|
|||
defaultProps.setProperty(Constants.PROPERTY_SESSION_INTERVAL, Integer.MAX_VALUE + "");
|
||||
md = md.toBuilder().defaultProperties(defaultProps).build();
|
||||
|
||||
Credentials creds = LoginCredentials.builder().user("user").build();
|
||||
Supplier<Credentials> creds = Suppliers.<Credentials> ofInstance(LoginCredentials.builder().user("user").build());
|
||||
|
||||
int session = Guice.createInjector(new BindProviderMetadataContextAndCredentials(md, creds)).getInstance(
|
||||
Key.get(int.class, Names.named(Constants.PROPERTY_SESSION_INTERVAL)));
|
||||
|
|
|
@ -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;
|
||||
|
||||
/**
|
||||
|
@ -81,8 +59,7 @@ public class AzureManagementRestClientModule extends RestClientModule<AzureManag
|
|||
.put(HostedServiceApi.class, HostedServiceAsyncApi.class)
|
||||
.put(OSImageApi.class, OSImageAsyncApi.class)
|
||||
.put(OperationApi.class, OperationAsyncApi.class)
|
||||
.put(DiskApi.class, DiskAsyncApi.class)
|
||||
.build();
|
||||
.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() {
|
||||
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
|
||||
*/
|
||||
|
@ -72,36 +77,64 @@ public class RequestAuthenticator implements HttpRequestFilter, RequestSigner {
|
|||
@Named(Constants.LOGGER_SIGNATURE)
|
||||
private Logger signatureLog = Logger.NULL;
|
||||
|
||||
final Provider<Calendar> calendarProvider;
|
||||
final Signature signer;
|
||||
final String apiVersion;
|
||||
private final Supplier<Credentials> creds;
|
||||
private final LoadingCache<Credentials, Signature> signerCache;
|
||||
private final Provider<Calendar> calendarProvider;
|
||||
private final HttpUtils utils;
|
||||
private 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();
|
||||
@Inject
|
||||
public SignatureForCredentials(Supplier<KeyStore> keyStore) {
|
||||
this.keyStore = checkNotNull(keyStore, "keyStore");
|
||||
}
|
||||
|
||||
@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());
|
||||
|
||||
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);
|
||||
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,33 +18,39 @@
|
|||
*/
|
||||
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
|
||||
|
@ -52,40 +58,58 @@ import static org.jclouds.oauth.v2.config.OAuthProperties.SIGNATURE_OR_MAC_ALGOR
|
|||
@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,
|
||||
public OAuthCredentialsSupplier(@Provider Supplier<Credentials> creds, OAuthCredentialsForCredentials loader,
|
||||
@Named(SIGNATURE_OR_MAC_ALGORITHM) String signatureOrMacAlgorithm) {
|
||||
this.identity = identity;
|
||||
this.privateKeyInPemFormat = privateKeyInPemFormat;
|
||||
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);
|
||||
// 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 {
|
||||
/**
|
||||
* 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)) {
|
||||
this.credentials = new OAuthCredentials.Builder().identity(identity).credential
|
||||
(privateKeyInPemFormat).build();
|
||||
return;
|
||||
return new OAuthCredentials.Builder().identity(identity).credential(privateKeyInPemFormat).build();
|
||||
}
|
||||
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();
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@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.
|
||||
|
@ -41,9 +44,8 @@ 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();
|
||||
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,9 +48,10 @@ 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),
|
||||
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