/* * Copyright 2016 the original author or authors. * * Licensed 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.gradle.api.internal.artifacts.repositories; import org.gradle.api.Action; import org.gradle.api.Nullable; import org.gradle.api.artifacts.repositories.AuthenticationContainer; import org.gradle.api.artifacts.repositories.PasswordCredentials; import org.gradle.api.credentials.AwsCredentials; import org.gradle.api.credentials.Credentials; import org.gradle.authentication.Authentication; import org.gradle.internal.Cast; import org.gradle.internal.artifacts.repositories.AuthenticationSupportedInternal; import org.gradle.internal.authentication.AllSchemesAuthentication; import org.gradle.internal.authentication.AuthenticationInternal; import org.gradle.internal.credentials.DefaultAwsCredentials; import org.gradle.internal.reflect.Instantiator; import java.util.Collection; import java.util.Collections; public class AuthenticationSupporter implements AuthenticationSupportedInternal { private final Instantiator instantiator; private final AuthenticationContainer authenticationContainer; private Credentials credentials; public AuthenticationSupporter(Instantiator instantiator, AuthenticationContainer authenticationContainer) { this.instantiator = instantiator; this.authenticationContainer = authenticationContainer; } @Override public PasswordCredentials getCredentials() { if (credentials == null) { return setCredentials(PasswordCredentials.class); } else if (credentials instanceof PasswordCredentials) { return Cast.uncheckedCast(credentials); } else { throw new IllegalStateException("Can not use getCredentials() method when not using PasswordCredentials; please use getCredentials(Class)"); } } @Override public <T extends Credentials> T getCredentials(Class<T> credentialsType) { if (credentials == null) { return setCredentials(credentialsType); } else if (credentialsType.isInstance(credentials)) { return Cast.uncheckedCast(credentials); } else { throw new IllegalArgumentException(String.format("Given credentials type '%s' does not match actual type '%s'", credentialsType.getName(), getCredentialsPublicType(credentials.getClass()).getName())); } } @Override public void credentials(Action<? super PasswordCredentials> action) { if (credentials != null && !(credentials instanceof PasswordCredentials)) { throw new IllegalStateException("Can not use credentials(Action) method when not using PasswordCredentials; please use credentials(Class, Action)"); } credentials(PasswordCredentials.class, action); } @Override public <T extends Credentials> void credentials(Class<T> credentialsType, Action<? super T> action) throws IllegalStateException { action.execute(getCredentials(credentialsType)); } @Override public void setConfiguredCredentials(Credentials credentials) { this.credentials = credentials; } private <T extends Credentials> T setCredentials(Class<T> clazz) { T t = newCredentials(clazz); credentials = t; return t; } private <T extends Credentials> T newCredentials(Class<T> clazz) { return instantiator.newInstance(getCredentialsImplType(clazz)); } @Override @Nullable public Credentials getConfiguredCredentials() { return credentials; } @Override public void authentication(Action<? super AuthenticationContainer> action) { action.execute(getAuthentication()); } @Override public AuthenticationContainer getAuthentication() { return authenticationContainer; } @Override public Collection<Authentication> getConfiguredAuthentication() { populateAuthenticationCredentials(); if (getConfiguredCredentials() != null & authenticationContainer.size() == 0) { return Collections.<Authentication>singleton(new AllSchemesAuthentication(getConfiguredCredentials())); } else { return getAuthentication(); } } private void populateAuthenticationCredentials() { // TODO: This will have to be changed when we support setting credentials directly on the authentication for (Authentication authentication : authenticationContainer) { ((AuthenticationInternal)authentication).setCredentials(getConfiguredCredentials()); } } // Mappings between public and impl types // If the list of mappings grows we should move it to a data structure private static <T extends Credentials> Class<? extends T> getCredentialsImplType(Class<T> publicType) { if (publicType == PasswordCredentials.class) { return Cast.uncheckedCast(DefaultPasswordCredentials.class); } else if (publicType == AwsCredentials.class) { return Cast.uncheckedCast(DefaultAwsCredentials.class); } else { throw new IllegalArgumentException(String.format("Unknown credentials type: '%s' (supported types: %s and %s).", publicType.getName(), PasswordCredentials.class.getName(), AwsCredentials.class.getName())); } } private static <T extends Credentials> Class<? super T> getCredentialsPublicType(Class<T> implType) { if (PasswordCredentials.class.isAssignableFrom(implType)) { return Cast.uncheckedCast(PasswordCredentials.class); } else if (AwsCredentials.class.isAssignableFrom(implType)) { return Cast.uncheckedCast(AwsCredentials.class); } else { throw new IllegalArgumentException(String.format("Unknown credentials implementation type: '%s' (supported types: %s and %s).", implType.getName(), DefaultPasswordCredentials.class.getName(), DefaultAwsCredentials.class.getName())); } } }