support changing credentials at runtime

This commit is contained in:
Adrian Cole 2013-01-15 21:25:51 -08:00
parent a9d335c6cc
commit a7e4564c8e
13 changed files with 172 additions and 181 deletions

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