Merge pull request #1181 from jclouds/dynamic-credentials

Dynamic credentials
This commit is contained in:
Adrian Cole 2013-01-16 06:44:00 -08:00
commit 4fbb70be7b
60 changed files with 1005 additions and 1070 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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());
}
};
}

View File

@ -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");
}

View File

@ -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);

View File

@ -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) {

View File

@ -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);
}
}

View File

@ -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"));
}

View File

@ -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());
}
};
}

View File

@ -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);

View File

@ -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());
}
}

View File

@ -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

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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());
}
};
}

View File

@ -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());
}
};
}

View File

@ -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());
}
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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();
}
}

View File

@ -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());
}
/**

View File

@ -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());

View File

@ -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 {
}

View File

@ -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 {
}

View File

@ -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")));

View File

@ -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

View File

@ -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())),

View File

@ -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=");
}
}

View File

@ -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() {

View File

@ -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)));

View File

@ -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();
}

View File

@ -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();

View File

@ -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;
}
}

View File

@ -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);
}
}
}

View File

@ -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);
}
}
}

View File

@ -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();
}
}

View File

@ -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;
}
}

View File

@ -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");
}

View File

@ -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;
}
}

View File

@ -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);
}
}
}

View File

@ -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);
}
}
}

View File

@ -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"); }
*/
}

View File

@ -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);
}
}

View File

@ -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);

View File

@ -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() {

View File

@ -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);
}
}

View File

@ -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();
}

View File

@ -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");

View File

@ -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");

View File

@ -69,7 +69,6 @@ public class OAuthCredentials extends Credentials {
return this;
}
@SuppressWarnings("unchecked")
public OAuthCredentials build() {
return new OAuthCredentials(checkNotNull(identity), credential, privateKey);
}

View File

@ -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"));
}
}

View File

@ -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();
}

View File

@ -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();
}

View File

@ -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);

View File

@ -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());
}
};
}

View File

@ -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;
}

View File

@ -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);

View File

@ -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) {

View File

@ -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.